Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 802233
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 14, 20262026-05-14T23:34:07+00:00 2026-05-14T23:34:07+00:00

I’ve successfully extended python with C, thanks to this handy skeleton module . But

  • 0

I’ve successfully extended python with C, thanks to this handy skeleton module. But I can’t find one for C++, and I have circular dependency trouble when trying to fix the errors that C++ gives when I compile this skeleton module.

How do you extend Python with C++?

I’d rather not depend on Boost (or SWIP or other libraries) if I don’t have to. Dependencies are a pain in the butt. Best case scenario, I find a skeleton file that already compiles with C++.

Here’s the edited skeleton I’ve made for C++:

#include <Python.h>

#include "Flp.h"

static PyObject * ErrorObject;

typedef struct {
    PyObject_HEAD
    PyObject * x_attr; // attributes dictionary
} FlpObject;

static void Flp_dealloc(FlpObject * self);
static PyObject * Flp_getattr(FlpObject * self, char * name);
static int Flp_setattr(FlpObject * self, char * name, PyObject * v);
DL_EXPORT(void) initflp();

static PyTypeObject Flp_Type = {
    /* The ob_type field must be initialized in the module init function
     * to be portable to Windows without using C++. */
    PyObject_HEAD_INIT(NULL)
    0,          /*ob_size*/
    "Flp",          /*tp_name*/
    sizeof(FlpObject),  /*tp_basicsize*/
    0,          /*tp_itemsize*/
    /* methods */
    (destructor)Flp_dealloc, /*tp_dealloc*/
    0,          /*tp_print*/
    (getattrfunc)Flp_getattr, /*tp_getattr*/
    (setattrfunc)Flp_setattr, /*tp_setattr*/
    0,          /*tp_compare*/
    0,          /*tp_repr*/
    0,          /*tp_as_number*/
    0,          /*tp_as_sequence*/
    0,          /*tp_as_mapping*/
    0,          /*tp_hash*/
};

#define FlpObject_Check(v) ((v)->ob_type == &Flp_Type)

static FlpObject * newFlpObject(PyObject * arg)
{
    FlpObject * self;
    self = PyObject_NEW(FlpObject, &Flp_Type);
    if (self == NULL)
        return NULL;
    self->x_attr = NULL;
    return self;
}

// Flp methods

static void Flp_dealloc(FlpObject * self)
{
    Py_XDECREF(self->x_attr);
    PyMem_DEL(self);
}

static PyObject * Flp_demo(FlpObject * self, PyObject * args)
{
    if (! PyArg_ParseTuple(args, ""))
        return NULL;
    Py_INCREF(Py_None);
    return Py_None;
}

static PyMethodDef Flp_methods[] = {
    {"demo",    (PyCFunction)Flp_demo,  1},
    {NULL,      NULL} // sentinel
};

static PyObject * Flp_getattr(FlpObject * self, char * name)
{
    if (self->x_attr != NULL) {
        PyObject * v = PyDict_GetItemString(self->x_attr, name);
        if (v != NULL) {
            Py_INCREF(v);
            return v;
        }
    }
    return Py_FindMethod(Flp_methods, (PyObject *)self, name);
}

static int Flp_setattr(FlpObject * self, char * name, PyObject * v)
{
    if (self->x_attr == NULL) {
        self->x_attr = PyDict_New();
        if (self->x_attr == NULL)
            return -1;
    }
    if (v == NULL) {
        int rv = PyDict_DelItemString(self->x_attr, name);
        if (rv < 0)
            PyErr_SetString(PyExc_AttributeError,
                    "delete non-existing Flp attribute");
        return rv;
    }
    else
        return PyDict_SetItemString(self->x_attr, name, v);
}
/* --------------------------------------------------------------------- */

/* Function of two integers returning integer */

static PyObject * flp_foo(PyObject * self, PyObject * args)
{
    long i, j;
    long res;
    if (!PyArg_ParseTuple(args, "ll", &i, &j))
        return NULL;
    res = i+j; /* flpX Do something here */
    return PyInt_FromLong(res);
}


/* Function of no arguments returning new Flp object */

static PyObject * flp_new(PyObject * self, PyObject * args)
{
    FlpObject *rv;

    if (!PyArg_ParseTuple(args, ""))
        return NULL;
    rv = newFlpObject(args);
    if ( rv == NULL )
        return NULL;
    return (PyObject *)rv;
}

/* Example with subtle bug from extensions manual ("Thin Ice"). */

static PyObject * flp_bug(PyObject * self, PyObject * args)
{
    PyObject *list, *item;

    if (!PyArg_ParseTuple(args, "O", &list))
        return NULL;

    item = PyList_GetItem(list, 0);
    /* Py_INCREF(item); */
    PyList_SetItem(list, 1, PyInt_FromLong(0L));
    PyObject_Print(item, stdout, 0);
    printf("\n");
    /* Py_DECREF(item); */

    Py_INCREF(Py_None);
    return Py_None;
}

/* Test bad format character */

static PyObject * flp_roj(PyObject * self, PyObject * args)
{
    PyObject *a;
    long b;
    if (!PyArg_ParseTuple(args, "O#", &a, &b))
        return NULL;
    Py_INCREF(Py_None);
    return Py_None;
}


/* List of functions defined in the module */

static PyMethodDef flp_methods[] = {
    {"roj",     flp_roj,     1},
    {"foo",     flp_foo,     1},
    {"new",     flp_new,     1},
    {"bug",     flp_bug,     1},
    {NULL,      NULL}       /* sentinel */
};


/* Initialization function for the module (*must* be called initflp) */

DL_EXPORT(void) initflp()
{
    PyObject *m, *d;

    /* Initialize the type of the new type object here; doing it here
     * is required for portability to Windows without requiring C++. */
    Flp_Type.ob_type = &PyType_Type;

    /* Create the module and add the functions */
    m = Py_InitModule("flp", flp_methods);

    /* Add some symbolic constants to the module */
    d = PyModule_GetDict(m);
    ErrorObject = PyErr_NewException("flp.error", NULL, NULL);
    PyDict_SetItemString(d, "error", ErrorObject);
}

This compiles fine for me, but when I test it:

$ python
Python 2.6.5 (r265:79063, Apr 16 2010, 13:57:41) 
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import flp
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: dynamic module does not define init function (initflp)
>>> 
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-14T23:34:08+00:00Added an answer on May 14, 2026 at 11:34 pm

    First of all, even though you don’t want to introduce an additional dependency, I suggest you to have a look at PyCXX. Quoting its webpage:

    CXX/Objects is a set of C++ facilities to make it easier to write Python extensions. The chief way in which PyCXX makes it easier to write Python extensions is that it greatly increases the probability that your program will not make a reference-counting error and will not have to continually check error returns from the Python C API. CXX/Objects integrates Python with C++ in these ways:

    • C++ exception handling is relied on to detect errors and clean up. In a complicated function this is often a tremendous problem when writing in C. With PyCXX, we let the compiler keep track of what objects need to be dereferenced when an error occurs.
    • The Standard Template Library (STL) and its many algorithms plug and play with Python containers such as lists and tuples.
    • The optional CXX/Extensions facility allows you to replace the clumsy C tables with objects and method calls that define your modules and extension objects.

    I think PyCXX is licensed under the BSD license, which means that you can just as well include the whole source code of PyCXX in the distributed tarball of your extension if your extension will be released under a similar license.

    If you really and absolutely don’t want to depend on PyCXX or any other third-party library, I think you only have to wrap functions that will be called by the Python interpreter in extern "C" { and } to avoid name mangling.

    Here’s the corrected code:

    #include <Python.h>
    
    #include "Flp.h"
    
    static PyObject * ErrorObject;
    
    typedef struct {
        PyObject_HEAD
        PyObject * x_attr; // attributes dictionary
    } FlpObject;
    
    extern "C" {
        static void Flp_dealloc(FlpObject * self);
        static PyObject * Flp_getattr(FlpObject * self, char * name);
        static int Flp_setattr(FlpObject * self, char * name, PyObject * v);
        DL_EXPORT(void) initflp();
    }
    
    static PyTypeObject Flp_Type = {
        /* The ob_type field must be initialized in the module init function
         * to be portable to Windows without using C++. */
        PyObject_HEAD_INIT(NULL)
        0,          /*ob_size*/
        "Flp",          /*tp_name*/
        sizeof(FlpObject),  /*tp_basicsize*/
        0,          /*tp_itemsize*/
        /* methods */
        (destructor)Flp_dealloc, /*tp_dealloc*/
        0,          /*tp_print*/
        (getattrfunc)Flp_getattr, /*tp_getattr*/
        (setattrfunc)Flp_setattr, /*tp_setattr*/
        0,          /*tp_compare*/
        0,          /*tp_repr*/
        0,          /*tp_as_number*/
        0,          /*tp_as_sequence*/
        0,          /*tp_as_mapping*/
        0,          /*tp_hash*/
    };
    
    #define FlpObject_Check(v) ((v)->ob_type == &Flp_Type)
    
    static FlpObject * newFlpObject(PyObject * arg)
    {
        FlpObject * self;
        self = PyObject_NEW(FlpObject, &Flp_Type);
        if (self == NULL)
            return NULL;
        self->x_attr = NULL;
        return self;
    }
    
    // Flp methods
    
    static void Flp_dealloc(FlpObject * self)
    {
        Py_XDECREF(self->x_attr);
        PyMem_DEL(self);
    }
    
    static PyObject * Flp_demo(FlpObject * self, PyObject * args)
    {
        if (! PyArg_ParseTuple(args, ""))
            return NULL;
        Py_INCREF(Py_None);
        return Py_None;
    }
    
    static PyMethodDef Flp_methods[] = {
        {"demo",    (PyCFunction)Flp_demo,  1},
        {NULL,      NULL} // sentinel
    };
    
    static PyObject * Flp_getattr(FlpObject * self, char * name)
    {
        if (self->x_attr != NULL) {
            PyObject * v = PyDict_GetItemString(self->x_attr, name);
            if (v != NULL) {
                Py_INCREF(v);
                return v;
            }
        }
        return Py_FindMethod(Flp_methods, (PyObject *)self, name);
    }
    
    static int Flp_setattr(FlpObject * self, char * name, PyObject * v)
    {
        if (self->x_attr == NULL) {
            self->x_attr = PyDict_New();
            if (self->x_attr == NULL)
                return -1;
        }
        if (v == NULL) {
            int rv = PyDict_DelItemString(self->x_attr, name);
            if (rv < 0)
                PyErr_SetString(PyExc_AttributeError,
                        "delete non-existing Flp attribute");
            return rv;
        }
        else
            return PyDict_SetItemString(self->x_attr, name, v);
    }
    /* --------------------------------------------------------------------- */
    
    /* Function of two integers returning integer */
    
    static PyObject * flp_foo(PyObject * self, PyObject * args)
    {
        long i, j;
        long res;
        if (!PyArg_ParseTuple(args, "ll", &i, &j))
            return NULL;
        res = i+j; /* flpX Do something here */
        return PyInt_FromLong(res);
    }
    
    
    /* Function of no arguments returning new Flp object */
    
    static PyObject * flp_new(PyObject * self, PyObject * args)
    {
        FlpObject *rv;
        
        if (!PyArg_ParseTuple(args, ""))
            return NULL;
        rv = newFlpObject(args);
        if ( rv == NULL )
            return NULL;
        return (PyObject *)rv;
    }
    
    /* Example with subtle bug from extensions manual ("Thin Ice"). */
    
    static PyObject * flp_bug(PyObject * self, PyObject * args)
    {
        PyObject *list, *item;
        
        if (!PyArg_ParseTuple(args, "O", &list))
            return NULL;
        
        item = PyList_GetItem(list, 0);
        /* Py_INCREF(item); */
        PyList_SetItem(list, 1, PyInt_FromLong(0L));
        PyObject_Print(item, stdout, 0);
        printf("\n");
        /* Py_DECREF(item); */
        
        Py_INCREF(Py_None);
        return Py_None;
    }
    
    /* Test bad format character */
    
    static PyObject * flp_roj(PyObject * self, PyObject * args)
    {
        PyObject *a;
        long b;
        if (!PyArg_ParseTuple(args, "O#", &a, &b))
            return NULL;
        Py_INCREF(Py_None);
        return Py_None;
    }
    
    
    /* List of functions defined in the module */
    
    static PyMethodDef flp_methods[] = {
        {"roj",     flp_roj,     1},
        {"foo",     flp_foo,     1},
        {"new",     flp_new,     1},
        {"bug",     flp_bug,     1},
        {NULL,      NULL}       /* sentinel */
    };
    
    
    /* Initialization function for the module (*must* be called initflp) */
    
    DL_EXPORT(void) initflp()
    {
        PyObject *m, *d;
    
        /* Initialize the type of the new type object here; doing it here
         * is required for portability to Windows without requiring C++. */
        Flp_Type.ob_type = &PyType_Type;
    
        /* Create the module and add the functions */
        m = Py_InitModule("flp", flp_methods);
    
        /* Add some symbolic constants to the module */
        d = PyModule_GetDict(m);
        ErrorObject = PyErr_NewException("flp.error", NULL, NULL);
        PyDict_SetItemString(d, "error", ErrorObject);
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a string like this: La Torre Eiffel paragonata all&#8217;Everest What PHP function
I have a jquery bug and I've been looking for hours now, I can't
this is what i have right now Drawing an RSS feed into the php,
I have this code to decode numeric html entities to the UTF8 equivalent character.
I have a French site that I want to parse, but am running into
I'm parsing an RSS feed that has an &#8217; in it. SimpleXML turns this
I have this code: - (void)parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock { NSString *someString = [[NSString
Seemingly simple, but I cannot find anything relevant on the web. What is the
Does anyone know how can I replace this 2 symbol below from the string
I have some data like this: 1 2 3 4 5 9 2 6

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.