在C ++中嵌入python,分段错误 [英] Embedding python in C++, Segmentation fault

查看:122
本文介绍了在C ++中嵌入python,分段错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将python脚本嵌入C ++应用程序中。
为了尝试集成,我做了一个试验代码:

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, *pModule, *pDict, *pFunc, *pValue;

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

    // Initialize the Python Interpreter
    Py_Initialize();

    // Build the name object
    pName = PyBytes_FromString(argv[1]);
    //std::to_string(argv[1]).encode(

    // Load the module object
    pModule = PyImport_Import(pName);

    // pDict is a borrowed reference 
    pDict = PyModule_GetDict(pModule);

    // pFunc is also a borrowed reference 
    pFunc = PyDict_GetItemString(pDict, argv[2]);

    if (PyCallable_Check(pFunc)) 
    {
        PyObject_CallObject(pFunc, NULL);
    } 
    else 
    {
        PyErr_Print();
    }

    // Clean up
    Py_DECREF(pModule);
    Py_DECREF(pName);

    // Finish the Python Interpreter
    Py_Finalize();

    return 0;
}


# Python script
def multiply():
    c = 12345*6789
    print ('The result of 12345 x 6789 :' + str(c))

我偶然发现了建议使用boost的帖子
boost是否比这更简单?简而言之:更少的代码,简单明了,很大程度上

I came across the posts that suggest to use boost. Is boost simpler than this? Def of simple: less code, straight forward, largely used by community.

我对这些问题感兴趣,因为我们要集成的实际代码非常复杂(因为不遵循编码规范),因此需要

I am interested in these questions because the real code we are going to integrate is pretty complex (because not following the coding ethics), and it needs to communicate with Python code at many times, hence there is synchronization issue as well.

推荐答案

使用<$ c可能会更容易$ c> boost :: python 或cython生成的代码。

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

罪魁祸首似乎是丢失的

PySys_SetArgv(argc, wargs);

其中 wargs 包含的参数为宽字符字符串。没有它,相对导入将不起作用。

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

以下代码(与gcc一起编译,如果 malloc())似乎起作用。

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;
}

这篇关于在C ++中嵌入python,分段错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆