Skip to content Skip to sidebar Skip to footer

Embedding Python In C++, Segmentation Fault

I am trying to embed python script in a c++ application. To try out the integration, I made a pilot code: // c++ code int main(int argc, char *argv[]) { PyObject *pName, *pMod

Solution 1:

It might be easier to use boost::python or the code generated by cython.

The main culprit seems to be the missing

PySys_SetArgv(argc, wargs);

where wargs contains the arguments as wide character strings. Without it, relative imports do not work.

The following code (compiled with gcc, g++ would require some casts in case of malloc()) seems to work.

#include <Python.h>
#include <string.h>

int to_wide_args(wchar_t **argsw[], int argc, char *argv[])
{
    int i;
    size_t len;
    wchar_t *wstr;
    wchar_t **tmp = NULL;
    tmp = malloc(sizeof(wchar_t **) * argc);

    for (i = 0; i < argc; i++) {
        /* In case of python 3.5, see Py_DecodeLocale */
        len = mbstowcs(NULL, argv[i], 0);
        wstr = malloc(sizeof(wchar_t) * (len + 1));
        if (len != mbstowcs(wstr, argv[i], len + 1)) {
            return -1;
        }
        tmp[i] = wstr;
    }
    *argsw = tmp;
    return 0;
}

int main(int argc, char *argv[])
{
    PyObject *dict = 0;
    PyObject *func = 0;
    PyObject *module = 0;

    wchar_t **wargs = NULL;
    int rc = 0;

    if (argc < 3) {
        printf("Usage: exe_name python_source function_name\n");
        return 1;
    }

    if (to_wide_args(&wargs, argc, argv) < 0) goto error;

    Py_SetProgramName(wargs[0]);
    Py_Initialize();
    PySys_SetArgv(argc, wargs);

    if (PyErr_Occurred()) goto error;

    module = PyImport_ImportModule(argv[1]);
    printf("Module ptr: %p\n", module);
    if (module == NULL || PyErr_Occurred()) goto error;

    dict = PyModule_GetDict(module);
    printf("Module dict ptr: %p\n", dict);
    if (dict == NULL || PyErr_Occurred()) goto error;

    func = PyDict_GetItemString(dict, argv[2]);
    printf("Function ptr: %p\n", func);
    if (func == NULL || PyErr_Occurred()) goto error;

    if (PyCallable_Check(func)) {
        PyObject_CallObject(func, NULL);
    } else {
        goto error;
    }
    goto ok;

error:
    PyErr_Print();
    rc = 1;
ok:
    Py_XDECREF(module);
    Py_Finalize();

    return rc;
}

Post a Comment for "Embedding Python In C++, Segmentation Fault"