我可以用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 ++名称在链接器中保存着比它们的“C”对应物更复杂的“损坏”名称,以便区分C ++允许的重载名称,即使对于非类函数也是如此。
您可以将函数声明为extern "C"
,以便使用C命名约定导出它。该函数的主体仍然可以使用c ++功能,但它应该对f2py或类似功能可见。
请注意,这会阻止您在该函数名称上使用C ++名称重载。