使用ctypes传递Python树对象到C++时遇未定义符号错误求助
问题原因及解决办法
核心问题:C++名字修饰导致符号无法识别
C++编译器默认会对函数名做名字修饰(Name Mangling),用来支持函数重载等特性,所以consumeTree编译后的实际符号名会变成类似_Z11consumeTreeP7PyObject的修改后字符串,而ctypes是按原函数名查找,自然找不到对应符号。
解决步骤
1. 用extern "C"包裹函数,禁用名字修饰
修改C++代码,将目标函数放在extern "C"块中,强制编译器按C语言规则生成符号:
#include <iostream> #include <Python.h> #define PY_SSIZE_T_CLEAN using namespace std; extern "C" { void consumeTree(PyObject *obj) { PyObject *printFunc, *result; printFunc = PyObject_GetAttrString(obj, "print"); result = PyObject_CallFunction(printFunc, NULL); cout << "Tree Representation: \n\n" << PyUnicode_AsUTF8(PyObject_Str(result)) << endl; // 释放Python对象,避免内存泄漏 Py_XDECREF(printFunc); Py_XDECREF(result); } }
2. 编译时正确链接Python库
编译动态库时必须指定Python头文件路径和链接库,以g++为例:
g++ -shared -fPIC -I$(python3 -c "import sysconfig; print(sysconfig.get_path('include'))") consume_tree.cpp -o libtest.so -lpython3.$(python3 -c "import sys; print(sys.version_info.minor)")
- 命令会自动获取当前Python的头文件路径和版本号,无需手动修改
3. 修正Python侧函数原型匹配
你的Python代码中,CFUNCTYPE的返回值类型写了ctypes.c_void_p,但C++函数返回的是void,需改成ctypes.c_void:
proto = ctypes.CFUNCTYPE(ctypes.c_void, ctypes.py_object)
内容的提问来源于stack exchange,提问作者Amol Borkar
相关产品推荐
相关产品推荐

