将.c文件重命名为.cpp,导入Cython库失败

2024-09-28 01:24:56 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个正在工作的Cython程序,它包装了一些C库和自定义C代码。最近,我不得不把我的项目转换成C++,所以我把所有的C代码都改写为^ {CD1}}。Cython编译得很好,并生成了.so文件。但是,当我尝试在Python中导入我的库时,我得到了以下错误。在

File "example.py", line 1, in <module>
    from tag36h11_detector import detect
ImportError: dlopen(/Users/ajay/Documents/Code/calibration/apriltag_detector/examples/tag36h11_detector.cpython-36m-darwin.so, 2): Symbol not found: _free_detection_payload
  Referenced from: /Users/ajay/Documents/Code/calibration/apriltag_detector/examples/tag36h11_detector.cpython-36m-darwin.so
  Expected in: flat namespace
 in /Users/ajay/Documents/Code/calibration/apriltag_detector/examples/tag36h11_detector.cpython-36m-darwin.so

因为我不确定错误的来源,我不确定应该提供什么相关信息。在

这是我的setup.py

^{pr2}$

我用python setup.py build_ext --inplace编译它

谢谢你的帮助!在


Tags: inpysocodecpythondetectorapriltagexamples
1条回答
网友
1楼 · 发布于 2024-09-28 01:24:56

language=c++添加到您的设置中:

setup(ext_modules=cythonize(Extension(
    name='XXX',
    ....
    language="c++",
 )))

你可能用gcc。GCC(和许多其他编译器)的前端决定了文件是否被编译成C(cc1)或C++(cc1+),这取决于它的扩展名:“.c”是C,“.cp”是C++。在

如果在设置中使用extra_compile_args=["-v"],,则可以确切地看到使用了哪个编译器:

  1. Cython创建了“tag36h11_detector.c”,由于它的扩展名,所以使用了c编译器(cc1)。在
  2. 对于文件“tag36h11_detector/tag36h11_探测器.cpp“C++编译器(cc1Pull)被使用。
<> > C和C++之间的区别之一是name mangling:c,期望对象文件中的符号名称不会被破坏,但是C++会对其进行修改。在

例如,对于一个具有签名的函数{{CD3>},C告诉链接器搜索一个名为^ {}的符号,但是C++生成了一个名为^ {}的符号,因此在链接步骤中找不到它。在

现在,连接期间会发生什么?在Linux上,链接共享对象的默认行为是,我们可以有未定义的符号。隐式地假定,当加载共享库时,这些符号将在运行时期间可用。这意味着只有在加载共享对象且无法找到符号时,即导入模块时,程序才会失败。在

您可以添加extra_link_args=["-Wl, no-undefined"],以确保如果存在未定义的符号,则编译将失败,以避免在运行时出现任何意外。在

一种修复方法,对于C++编译器来说,可以在代码中使用^ {CD7}}来发出未加密的名称,正如注释中所指出的那样。在

一种较少的侵入性方法是向编译器说明,C++ +约定是通过添加^ {CD8>}到安装程序中使用的。在

使用language="c++",Cython创建了“三十、 cpp公司(而不是“XXX.c”)来自三十、 pyx公司因此,GCC选择Cython文件的C++编译器,它知道正确的名称的修改。在

相关问题 更多 >

    热门问题