将 C++ 源代码用于 f2py 时未定义的符号
Undefined symbol when using C++ source for f2py
我可以用 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.
啊,这几乎可以肯定是名称修改的问题。
C++ 名称保存在链接器中,其 "mangled" 名称比 "C" 名称复杂得多,以便区分 C++ 允许的重载名称,即使是非 class 函数.
您可以将函数声明为 extern "C"
,以便使用 C 命名约定导出它。函数体仍然可以使用 c++ 特性,但它应该对 f2py 或类似的可见。
请注意,这会阻止您对该函数名称使用 C++ 名称重载。
我可以用 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.
啊,这几乎可以肯定是名称修改的问题。
C++ 名称保存在链接器中,其 "mangled" 名称比 "C" 名称复杂得多,以便区分 C++ 允许的重载名称,即使是非 class 函数.
您可以将函数声明为 extern "C"
,以便使用 C 命名约定导出它。函数体仍然可以使用 c++ 特性,但它应该对 f2py 或类似的可见。
请注意,这会阻止您对该函数名称使用 C++ 名称重载。