0

I'm trying to extend the Python interpreter in my C++ program, my problem is as follows.
When I'm trying to call a function, explained in the code below, I get a NameError, from the Python interpreter. The error is

Traceback (most recent call last):
File "", line 3, in module
NameError: name 'func' is not defined

I used the following code to bind it, according to the Python wiki for version 3.3.2, which I'm using here

double func( int a )
{
    return a*a-0.5;
}

static PyObject *TestError;
static PyObject * func_test(PyObject * self, PyObject *args)
{
    const int * command;
    double sts;
    if( !PyArg_ParseTuple(args, "i", &command) )
        return NULL;
    sts = func( *command );
    return PyFloat_FromDouble(sts);
}

static PyMethodDef TestMethods[] = {
    {"func",  func_test, METH_VARARGS,
     "Thing."},
    {NULL, NULL, 0, NULL}        /* Sentinel */
};

static struct PyModuleDef testmodule = {
   PyModuleDef_HEAD_INIT,
   "test",   /* name of module */
   NULL, /* module documentation, may be NULL */
   -1,       /* size of per-interpreter state of the module,
            or -1 if the module keeps state in global variables. */
   TestMethods
};

PyMODINIT_FUNC PyInit_test()
{
    PyObject *m;
    m = PyModule_Create(&testmodule);
    if (m == NULL)
        return NULL;
    TestError = PyErr_NewException("test.error", NULL, NULL);
    Py_INCREF(TestError);
    PyModule_AddObject(m, "error", TestError);
    return m;
}


Then I'm calling PyImport_AppendInittab("test", PyInit_test);
Py_Initialize();, and then I'm trying to run a simple test, with

    PyRun_SimpleString("import test\n"
                       "print('Hi!')\n"
                       "b = func(5)\n"
                       "print(b)\n");

Yet, I keep getting the error. Can someone please explain, what am I doing wrong here?

2 Answers 2

1
PyRun_SimpleString("import test\n"
                   "print('Hi!')\n"
                   "b = test.func(5)\n"   # <--
                   "print(b)\n");

EDIT: Another problem:

int command;   // not "int *"
double sts;
if( !PyArg_ParseTuple(args, "i", &command) )

Note that I'd recommend using CFFI if you're not familiar yet with how to write a CPython C extension module.

Sign up to request clarification or add additional context in comments.

Comments

0

I agree with all the fixes by Armin Rigo and I would add this one:
PyImport_AppendInittab("test", &PyInit_test);

Pass the address of the function to PyImport_AppendInittab.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.