用ctypes实现Python与Fortran模块的接口

2024-10-02 14:25:13 发布

您现在位置:Python中文网/ 问答频道 /正文

我用Fortran编写了这个模块:

  MODULE utils
  IMPLICIT NONE
  PUBLIC
  INTEGER :: num_atom ! number of atoms in one configuration
    CONTAINS
      SUBROUTINE readin
      IMPLICIT NONE
      INTEGER :: iargc, ndim, i

     END SUBROUTINE readin

     SUBROUTINE convert
     IMPLICIT NONE
     REAL :: x,y,z
     END SUBROUTINE convert

我通过以下方式编制:

^{pr2}$

因此,在尝试从以下python代码调用函数“readin”时:

import os
_path = os.path.dirname(os.path.realpath(__file__)) + "/" + "somelib.so"

from ctypes import cdll, byref, c_int, c_double, c_char
lib_polint = cdll.LoadLibrary(_path)

def A():
    a = lib_polint.readin_

A()

我无法识别函数名到“有点不对劲”并出现以下错误:

“未定义符号:读取”。在

如果我移除模块并只保留子例程“readin”,它就可以工作了。 怎么处理?在


Tags: 模块pathimportnoneconvertoslibinteger
2条回答

从共享库转储符号

$ nm -D somelib.so
0000000000201020 B __bss_start
                 w __cxa_finalize
0000000000201020 D _edata
0000000000201028 B _end
00000000000006f4 T _fini
                 w __gmon_start__
00000000000005a0 T _init
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
                 w _Jv_RegisterClasses
00000000000006e0 T __utils_MOD_convert
0000000000201024 B __utils_MOD_num_at
00000000000006f0 T __utils_MOD_readin

看起来你的子程序在一个模块中影响了符号名。不是readin_,而是__utils_MOD_readin。如果你把模块的名字放在最上面,那么你就把它放在最上面。在

作为记录,我只是报告我在我的系统上看到的。我不熟悉fortran,不知道是否可以跨编译器使用这种命名。在

使用Fortran与C的互操作性,将链接器符号设置为任何您想要的符号

 SUBROUTINE readin bind(C, name="readin")
  INTEGER :: iargc, ndim, i

 END SUBROUTINE readin

现在子例程作为一个外部可见的C函数的名称将只是readin,您不必担心名称的损坏。在

如果没有模块,您可以打赌名称是_readin,但也可以是readin_或{},但不是经常这样。在

对于模块来说,这是一种抽奖,不同编译器的名称不同。使用这些符号是没有意义的。在

相关问题 更多 >