嵌入Python模块链接大共享库时出现PyLong_AsLongLongAndOverflow未定义错误
问题成因分析
当你将嵌入式Python包装器链接到大型共享库时,出现ImportError: undefined symbol: PyLong_AsLongLongAndOverflow的核心原因是Python共享库的符号未全局暴露:
- 单独编译可执行程序时,链接器会将libpython的符号默认设置为全局可见,Python加载math这类C扩展模块时,能直接解析到所需的Python API符号。
- 但链接成共享库时,默认情况下链接器会将依赖库(包括libpython)的符号标记为局部,仅在共享库内部可见。当Python动态加载math.so这类扩展模块时,模块无法从进程中找到PyLong_AsLongLongAndOverflow等符号,导致导入失败。
解决方案
Linux平台(替代粗糙的dlopen方法)
编译共享库时添加链接选项,强制导出所有符号:
- 使用GCC编译时,添加
-Wl,-E参数:g++ -shared -o your_lib.so your_source.cpp -lpython3.11 -Wl,-E - 或者使用
-Wl,--export-dynamic,效果类似,确保Python的API符号全局可见,让后续加载的扩展模块能解析到。
Windows平台
Windows下的核心是确保Python运行时库被正确加载,且符号可被扩展模块访问:
- 显式加载Python运行时:
在你的共享库入口(比如DllMain)中,提前加载python311.dll:#include <windows.h> BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: // 加载Python运行时库,确保路径正确 LoadLibraryW(L"python311.dll"); break; } return TRUE; } - 确保链接和路径正确:
- 链接时必须链接python311.lib(Python安装目录下的libs文件夹)。
- 将python311.dll放在你的共享库同一目录,或者添加到系统PATH中,避免加载失败。
附:原始测试代码
ez_dxf_wrap.py
import ezdxf doc = None msp = None def print_entity(e): print("LINE on layer: %s\n" % e.dxf.layer) print("start point: %s\n" % e.dxf.start) print("end point: %s\n" % e.dxf.end) def load_dxf_document(filepath): global doc global msp doc = ezdxf.readfile(filepath) msp = doc.modelspace() print(msp) for e in msp: print(e) if e.dxftype() == "LINE": print_entity(e) return True
临时粗糙解决方法(Linux)
#include <dlfcn.h> dlopen("libpython3.11.so", RTLD_LAZY | RTLD_GLOBAL);
内容的提问来源于stack exchange,提问作者Sean McBride
相关产品推荐
相关产品推荐

