2016-01-05 42 views
2

我想通過Cython將字符串從Python傳遞到Fortran,但是我無法使其正常工作。 我成功地通過了使用numpy數組的真實列表,所以我試圖通過將我的字符串轉換爲我的Cython例程中的一個char數組並將此數組傳遞給Fortran,但我沒有在Fortran中獲得正確的char *常規。通過Cython從Python傳遞字符串到Fortran

我試圖按照這裏給出的信息: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) 

文件實施例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=� 

回答

3

由於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) 

文件實施例H

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

然後用Cython代碼似乎正常工作:

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

非常感謝。現在它工作得很好。 – Mazkime