通过 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
我正在尝试使用 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