我想在c ++应用程序中嵌入python脚本。 为了尝试整合,我制作了一个试验代码:
// 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))
我遇到了建议使用提升的帖子。 提升比这简单吗?简单明了:代码少,直接,主要由社区使用。
我对这些问题很感兴趣,因为我们要集成的真实代码非常复杂(因为不遵循编码伦理),并且需要多次与Python代码进行通信,因此也存在同步问题。
答案 0 :(得分:-1)
使用boost::python
或cython生成的代码可能更容易。
主要罪魁祸首似乎是缺失
PySys_SetArgv(argc, wargs);
其中wargs
包含作为宽字符串的参数。没有它,相对进口不起作用。
以下代码(使用gcc编译,g ++需要在malloc()
的情况下进行一些强制转换)似乎可行。
#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;
}