Search code examples
c++pythoncpython-c-apipython-embedding

Embedded Python 2.7.2 Importing a module from a user-defined directory


I'm embedding Python into a C/C++ application that will have a defined API.

The application needs to instantiate classes defined in a script, which are structured roughly like this:

class userscript1:
    def __init__(self):
        ##do something here...

    def method1(self):
        ## method that can be called by the C/C++ app...etc

I've managed in the past (for the proof-of-concept) to get this done using the following type of code:

PyObject* pName = PyString_FromString("userscript.py");
PyObject* pModule = PyImport_Import(pName);
PyObject* pDict = PyModule_GetDict(pModule);
PyObject* pClass = PyDict_GetItemString(pDict, "userscript");
PyObject* scriptHandle = PyObject_CallObject(pClass, NULL);

Now that I'm in more of a production environment, this is failing at the PyImport_Import line - I think this might be because I'm trying to prepend a directory to the script name, e.g.

PyObject* pName = PyString_FromString("E:\\scriptlocation\\userscript.py");

Now, to give you an idea of what I've tried, I tried modifying the system path before all of these calls to make it search for this module. Basically tried modifying sys.path programmatically:

PyObject* sysPath = PySys_GetObject("path");
PyObject* path = PyString_FromString(scriptDirectoryName);
int result = PyList_Insert(sysPath, 0, path);

These lines run ok, but have no effect on making my code work. Obviously, my real code has a boatload of error checking that I have excluded so don't worry about that!

So my question: how do I direct the embedded interpreter to my scripts appropriately so that I can instantiate the classes?


Solution

  • you need to specify userscript and not userscript.py also use PyImport_ImportModule it directly takes a char *

    userscript.py means module py in package userscript

    this code works for me:

    #include <stdio.h>
    #include <stdlib.h>
    #include <Python.h>
    
    int main(void)
    {
        const char *scriptDirectoryName = "/tmp";
        Py_Initialize();
        PyObject *sysPath = PySys_GetObject("path");
        PyObject *path = PyString_FromString(scriptDirectoryName);
        int result = PyList_Insert(sysPath, 0, path);
        PyObject *pModule = PyImport_ImportModule("userscript");
        if (PyErr_Occurred())
            PyErr_Print();
        printf("%p\n", pModule);
        Py_Finalize();
        return 0;
    }