在C ++中嵌入python,分段错误 [英] Embedding python in C++, Segmentation fault
问题描述
我正在尝试将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屋!