【发布时间】:2019-06-17 13:45:58
【问题描述】:
我想在 c++ 中嵌入用 3.5 版编写的 python 代码。此外,python 脚本需要作为整个脚本重复执行。我的代码如下。它在第一次迭代时执行良好,在第二次迭代时出现分段错误。
main.cpp:
#include <Python.h>
#include<iostream>
using namespace std;
int main(int argc, char *argv[])
{
int i = 0;
while(i<3){
cout<<"start"<<endl;
Py_Initialize();
FILE* file;
wchar_t* _argv[argc];
for(int i=0; i<argc; i++){
wchar_t *arg = Py_DecodeLocale(argv[i], NULL);
_argv[i] = arg;
}
PySys_SetArgv(argc, _argv);
PyObject *sys = PyImport_ImportModule("sys");
PyObject *path = PyObject_GetAttrString(sys, "path");
PyList_Append(path, PyUnicode_FromString("."));
file = fopen("./example.py","r");
PyRun_SimpleFile(file, "./example.py");
fclose(file);
Py_Finalize();
cout<<"Done"<<endl;
i++;
}
return 0;
}
example.py:
import tensorflow as tf
flags = tf.app.flags
FLAGS = flags.FLAGS
flags.DEFINE_float('learning_rate', 0.01, 'initial learning rate')
def main(argv=None):
print(FLAGS.learning_rate)
if __name__ == '__main__':
main()
我使用以下方法构建项目:
cmake --build . --target Demo -- -j 2
并执行为:
./Demo --learning_rate 0.02
输出是:
start
0.02
Done
start
Segmentation fault (core dumped)
然后我将“example.py”的内容替换为:
print("Hi")
输出是:
start
Hi
Done
start
Hi
Done
start
Hi
Done
如何解决上述分段错误?
【问题讨论】:
-
您正在泄漏内存。虽然不是段错误的原因
-
每次迭代都不需要初始化和完成python解释器
-
如果我在循环之外进行初始化和完成,我会收到以下错误:absl.flags._exceptions.DuplicateFlagError:标志“learning_rate”被定义了两次。第一个来自 ./Demo,第二个来自 ./Demo。首次出现的描述:初始学习率
-
您还应该在调用
Py_Initialize之前使用Py_SetPath,而不是导入sys并更改path。这是正确的方法(只要在运行时不需要更改)。无论如何,很难判断出了什么问题,因为您实际上并没有任何错误检查。就像任何东西都可以返回一个 nullptr -
是的,因为那时文件已经加载了。您应该将东西包装在一个函数或其他东西中并多次调用它。重新初始化和关闭 python 解释器的成本很高。
标签: c++ python-3.x embedding