为 f2py 使用 C++ 源时未定义的符号
Posted
技术标签:
【中文标题】为 f2py 使用 C++ 源时未定义的符号【英文标题】:Undefined symbol when using C++ source for f2py 【发布时间】:2018-01-04 13:51:58 【问题描述】:我可以用 f2py
包装一个 C 函数,如下所示:
foo.c
#include <stdio.h>
void func(int n, int * a)
printf("%d\n", n);
对应的接口文件是
foo.pyf
python module foo
interface
subroutine func(n, a)
intent(c) func
intent(c)
integer, intent(hide) :: n = shape(a,0)
real(kind=8), dimension(n), intent(in) :: a
end subroutine func
end interface
end python module foo
然后,我执行f2py foo.pyf -c foo.c -m foo
,它会创建 Python 库,例如代码
import numpy as np
import foo
foo.func( np.ones(3) )
如您所愿打印3
。
问题:更改foo.c
→ foo.cpp
导致未定义符号
通过将foo.c
的扩展名更改为foo.cpp
,我注意到
f2py foo.pyf -c foo.cpp -m foo
调用g++
而不是gcc
。美好的。但是,之后当我在 Python 中执行 import foo
时,我看到了:
Traceback (most recent call last):
File "<string>", line 1, in <module>
ImportError: ./foo.so: undefined symbol: func_
我必须应用什么魔法才能使f2py
与 C++ 代码一起工作?有可能吗?
补充说明:
如果我删除接口文件中的intent(c) foo
行,那么foo.c
会产生相同的行为,即它与f2py
一起编译时,从Python 导入时会出现相同的未定义符号错误。
【问题讨论】:
您究竟为什么要尝试通过f2py
为C(和C++)函数生成Python 绑定?该程序用于为 Fortran 函数生成绑定。
getting started guide 表示它可以用于 C 和 Fortran。请参阅this also(虽然有些过时)。
【参考方案1】:
啊,这几乎肯定是名称修改的问题。
C++ 名称保存在链接器中,其“错位”名称比“C”对应名称要复杂得多,以便区分 C++ 允许的重载名称,即使是非类函数。
您可以将函数声明为extern "C"
,以便使用C 命名约定导出它。函数的主体仍然可以使用 c++ 功能,但它应该对 f2py 或类似的可见。
请注意,这会阻止您在该函数名称上使用 C++ 名称重载。
【讨论】:
是的,这行得通。谢谢。我在foo.cpp
中的void func ...
之前添加了extern "C"
。
当然,如果你能找到一个cpp2py,那就更好了。以上是关于为 f2py 使用 C++ 源时未定义的符号的主要内容,如果未能解决你的问题,请参考以下文章
ImportError:在 python 中导入 swigged c++-class 时未定义的符号