解析器.cpp:
#include <python3.4/Python.h>
#include <fstream>
#include <string>
#include <vector>
#include <iostream>
using namespace std;
extern "C"
{
PyObject* test(const char* filename)
{
size_t LIM = 1000;
PyObject* result = PyList_New(LIM);
for (size_t i = 0; i < LIM; i++) {
PyObject * t = PyList_New(0);
PyList_Append(t, PyLong_FromLong(1));
cout << i << "/" << PyList_Size(result) << " " << t << endl;
if (PyList_SetItem(result, i, t) != 0) {
cout << "!" << endl;
}
}
Py_INCREF(result);
return result;
}
}
编译:
g++ -O2 -fPIC -std=c++11 -shared -o parser_c.so parser_c.cpp -lpython3.4m
测试.py:
import ctypes
import datetime
p = ctypes.CDLL('./parser_c.so')
p.test.restype = ctypes.py_object
print(p.test("asd"))
执行 python3 test.py 因段错误而终止,我通过调试输出得到的最后一行是
381/1000 0x7f0996bb5a88
此外,如果我不在 test.py 中导入 datetime 或在 parser.cpp 中减少 LIM,它也可以正常工作。
我不明白为什么会发生这种情况。
有人可以帮助我吗?
最佳答案
问题在于 ctypes 释放了全局解释器锁,因此对 Python api 函数的调用未定义
The Python global interpreter lock is released before calling any function exported by these libraries, and reacquired afterwards.
您需要在函数开始时重新获取它,并在函数结束时重新释放它:
PyObject* test(const char* filename)
{
PyGILState_STATE gstate = PyGILState_Ensure();
// The bulk of your code stays the same and goes here ...
PyGILState_Release(gstate);
return result;
}
关于python - 在 Python C 扩展中创建 PyList_New 时出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35774011/