使用带接口的 f2py 编译模块

Compiling a module with f2py with an interface

我正在尝试用 f2py 编译一个 fortran 模块。就是下面的代码

module my_log_mod

   implicit none

    interface my_log
        module procedure my_log_array
        module procedure my_log_vector
    end interface my_log

   private  ! hides items not listed on public statement 
   public :: my_log


contains

    subroutine my_log_array(a,res)
        double precision, dimension (:,:), intent (in) :: a
        double precision, dimension (:,:), intent (out) :: res

        where (a>1.0)
            res = log(a)
        else where
            res = 0.D0
        end where
    end subroutine  

    subroutine my_log_vector(a,res)
        double precision, dimension (:), intent (in) :: a
        double precision, dimension (:), intent (out) :: res

        where (a>1.0)
            res = log(a)
        else where
            res = 0.D0
        end where
    end subroutine  

end module my_log_mod   

我用下面的命令编译

f2py.py -c -m my_log_mod_comp my_log_mod.f90

并导致以下错误

C:\Users\weisshau\AppData\Local\Temp\tmpf0apqa7s\src.win32-3.6\my_log_mod_comp-f2pywrappers2.f90:7:28:

       use my_log_mod, only : my_log_array
                            1
Error: Symbol 'my_log_array' referenced at (1) not found in module 'my_log_mod'
C:\Users\weisshau\AppData\Local\Temp\tmpf0apqa7s\src.win32-3.6\my_log_mod_comp-f2pywrappers2.f90:18:28:

       use my_log_mod, only : my_log_vector
                            1
Error: Symbol 'my_log_vector' referenced at (1) not found in module 'my_log_mod'

我不太了解 fortran 和 f2py,所以我不知道发生了什么。如果我在纯 Fortran 中使用该模块,它会很好地工作

F2py 似乎正在创建另一个包装器代码,它使用您模块中的子例程。

但是它直接调用子程序my_log_vectormy_log_array。好像f2py不支持private。我会删除 private.

还要做好准备,您将无法在 Python 中使用通用 my_log。这种泛型概念与 Python 格格不入。如果删除 private 不能使其可编译,您可能需要删除通用接口。你绝对应该删除 public :: my_log.

遗憾的是,f2py 不支持现代 Fortran 的所有功能。

我测试的代码:

module my_log_mod

   implicit none

    interface my_log
        module procedure my_log_array
        module procedure my_log_vector
    end interface my_log

contains

    subroutine my_log_array(a,res)
        double precision, dimension (:,:), intent (in) :: a
        double precision, dimension (:,:), intent (out) :: res

        where (a>1.0)
            res = log(a)
        else where
            res = 0.D0
        end where
    end subroutine  

    subroutine my_log_vector(a,res)
        double precision, dimension (:), intent (in) :: a
        double precision, dimension (:), intent (out) :: res

        where (a>1.0)
            res = log(a)
        else where
            res = 0.D0
        end where
    end subroutine  

end module my_log_mod   

编译:

f2py -c -m my_log_mod_comp my_log_mod.f90

...

Post-processing...
        Block: my_log_mod_comp
                        Block: my_log_mod
                                Block: my_log
                                Block: my_log_array
                                Block: my_log_vector
Post-processing (stage 2)...
        Block: my_log_mod_comp
                Block: unknown_interface
                        Block: my_log_mod
                                Block: my_log_array
                                Block: my_log_vector
Building modules...
        Building module "my_log_mod_comp"...
                Constructing F90 module support for "my_log_mod"...
                Creating wrapper for Fortran subroutine "my_log_array"
                      res = my_log_array(a)
                          res = my_log_array(a)
                Creating wrapper for Fortran subroutine "my_log_vector"("my_log_vector")...
                        Constructing wrapper function "my_log_mod.my_log_vector"...
                          res = my_log_vector(a)
        Wrote C/API module "my_log_mod_comp" to file "/tmp/tmp7e5v0u/src.linux-x86_64-2.7/my_log_mod_compmodule.c"
        Fortran 90 wrappers are saved to "/tmp/tmp7e5v0u/src.linux-x86_64-2.7/my_log_mod_comp-f2pywrappers2.f90"

...

gfortran:f90: /tmp/tmp7e5v0u/src.linux-x86_64-2.7/my_log_mod_comp-f2pywrappers2.f90
/usr/bin/gfortran -Wall -g -Wall -g -shared /tmp/tmp7e5v0u/tmp/tmp7e5v0u/src.linux-x86_64-2.7/my_log_mod_compmodule.o /tmp/tmp7e5v0u/tmp/tmp7e5v0u/src.linux-x86_64-2.7/fortranobject.o /tmp/tmp7e5v0u/my_log_mod.o /tmp/tmp7e5v0u/tmp/tmp7e5v0u/src.linux-x86_64-2.7/my_log_mod_comp-f2pywrappers2.o -L/usr/lib64 -lpython2.7 -lgfortran -o ./my_log_mod_comp.so
Removing build directory /tmp/tmp7e5v0u