【问题标题】:Creating a Python module from Fortran source code using SWIG使用 SWIG 从 Fortran 源代码创建 Python 模块
【发布时间】:2016-01-02 16:23:59
【问题描述】:

我正在从事一个项目,该项目涉及为用 Fortran 编写的程序创建 Python 接口。我做了一些研究并决定使用 SWIG,首先将 Fortran 例程暴露给 C++,然后用 SWIG 包装它们。但是,我无法让 Python 模块工作。

例如,我有这个 Fortran 函数:

function sum_array(input_array, length) result(sum)

implicit none

integer, value, intent(in) :: length
real(kind=8), intent(in), dimension(length) :: input_array

real(kind=8) :: sum
integer :: i

sum = 0.0

do i=1, length
   sum = sum + input_array(i)
end do

end function sum_array

使用 C 声明:

double sum_array(double* input_array, int length);

我使用的 SWIG 接口文件是:

%module sum_array

%{
   #define SWIG_FILE_WITH_INIT
   #include "sum_array.h"
%}

%include "numpy.i"

%init %{
   import_array();
%}

%apply (double* IN_ARRAY1, int DIM1) {(double* input_array, int length)};

%include "sum_array.h"

此接口文件使用 numpy.i 接口。

我正在将此代码(使用 make)编译成一个共享对象,如下所示:

$ swig -python -c++ -o sum_array_wrap.cpp sum_array.i
$ gfortran -c sum_array.f90 -o sum_array.o -fpic -fno-underscoring 
$ gcc -I/usr/include/python2.7 -c sum_array_wrap.cpp -o sum_array_wrap.o -fpic -std=c++0x
$ gfortran sum_array_wrap.o sum_array.o -o _sum_array.so -shared -Wl,-soname,_sum_array.so -lstdc++

当我尝试在 Python 中导入模块时,我得到“NameError: name 'sum_array' is not defined”,来自:

from numpy.random import rand
from _sum_array import *

input_array = rand(5)
sum = sum_array(input_array)

根据我从解释器中的 help() 获得的信息,我认为链接器不包括库中的 sum_array 函数,我认为这是问题所在。

关于如何让它发挥作用的任何想法?

顺便说一句,非常欢迎关于其他工具而不是 SWIG 的建议,因为这是我第一次这样做,我尝试这样做的唯一方法就是这个。

【问题讨论】:

  • _sum_array 导入哪些变量或函数?
  • 你的意思是当我在 Python 中导入模块时?好像是空的,我认为链接器没有找到函数sum_array的声明...

标签: python c++ numpy fortran swig


【解决方案1】:

这次问题出在name mangling。 fortran sompiler 不使用它,因此导出符号名称为 sym_array,但稍后您使用 C++ 编译接口,因此链接器希望看到类似 _Z9sum_arrayPdi 的内容。解决方法是将header内容包装成

#ifdef __cplusplus
extern "C" {
#endif

double sum_array(double* input_array, int length);

#ifdef __cplusplus
}
#endif

【讨论】:

  • 我的错,那行是错误的,虽然我没有使用它,我添加它是为了避免在编译 Python 接口时出现警告。当我使用没有该行的 .i 文件时,尝试在解释器中导入模块时,我得到“ImportError: /home/manuel/Documents/typemaps/fortran/_sum_array.so: undefined symbol: _Z9sum_arrayPdi”。
  • 这意味着sum_array 的依赖没有解决。如果您使用正确的来源更新帖子,我可能会为您提供帮助。
  • 我修复了接口文件,但仍然无法正常工作。
  • @Manolo 我很高兴它有帮助。我想你现在可以接受答案了 ;-)
猜你喜欢
  • 2011-02-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-01
  • 1970-01-01
  • 2015-12-23
  • 2011-02-25
  • 1970-01-01
相关资源
最近更新 更多