通过 Cython 将字符串从 Python 传递给 Fortran

Passing a string from Python to Fortran through Cython

我正在尝试使用 Cython 将字符串从 Python 传递到 Fortran,但我无法使其正常工作。 我使用 numpy 数组成功传递了真实列表,所以我尝试通过在我的 Cython 例程中将我的字符串转换为 char 数组并将该数组传递给 Fortran 来做类似的事情,但我没有在 Fortran 例程中得到正确的 char* .

我尝试遵循此处给出的信息:http://docs.cython.org/src/tutorial/strings.html,尤其是需要使用 encode() 方法将我的 python 字符串转换为 C char*,但它没有正常工作。

如能提供帮助使其正常工作,我们将不胜感激。这是一个最小的工作示例:

文件ex.pyx

cdef extern from "ex.h":
    void fortfunction(int* nchar, char** outputFile)

def f(str file):

    ftmp = file.encode('UTF-8')
    cdef char* outputFile = ftmp
    cdef int   nchar      = len(file)

    fortfunction(&nchar, &outputFile)

文件ex.h

extern void fortfunction(int* nchar, char** outputFile);

文件 ex.f90

module ex

  use iso_c_binding
  implicit none
  contains

  subroutine fortfunction(nchar,outputFile) bind(c)
  implicit none
  integer(c_int),    intent(in) :: nchar
  character(c_char), intent(in) :: outputFile(nchar)
  print*,'outputFile=',outputFile
  end subroutine fortfunction

end module ex

文件setup.py

from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
from os import system

# compile the fortran modules without linking
system('ifort ex.f90 -c -o ex.o -fPIC -nofor_main')

ext_modules = [Extension('ex',                        # module name:
                         ['ex.pyx'],                  # source file:
                         extra_link_args=['-limf','-lifcore','ex.o'])]   # other files to link to

setup(name = 'mymodule',
      cmdclass = {'build_ext': build_ext},
      ext_modules  = ext_modules)

构建包,运行python setup.py build_ext --inplace 这是我最终得到的

>>> import ex
>>> ex.f('foo')
 outputFile=�

因为ex.f90中的伪参数outputFile(nchar)是一个character(c_char)的数组,它接收的是这个数组第一个元素的地址。所以我认为我们应该传递 char* 而不是 char**,这样

文件ex.pyx

cdef extern from "ex.h":
    void fortfunction(int* nchar, char* outputFile)

def f(str file):
    ftmp = file.encode('UTF-8')
    cdef char* outputFile = ftmp
    cdef int   nchar      = len(file)  

    fortfunction(&nchar, outputFile)

文件ex.h

extern void fortfunction(int* nchar, char* outputFile);

那么 Cython 代码似乎可以正常工作:

>>> import ex
>>> ex.f( 'foo' )
  outputFile=foo