我目前正在尝试将字符串传递给Fortran库。我已经从这个库中获得了其他函数,但是这个特殊的函数似乎是唯一的,因为它希望将一个字符串传递给它作为函数的参数。
查看源代码,该函数需要三个参数
SUBROUTINE EZVOLLIB(VOLEQI,DBHOB,HTTOT,VOL)
并且定义了参数:
IMPLICIT NONE
CHARACTER*(*) VOLEQI
CHARACTER*10 VOLEQ
REAL DBHOB,HTTOT,TOPD, VOL(15), MHT
INTEGER REGN,ERRFLG
在Python中,我对函数的调用看起来像
from ctypes import *
mylib = cdll.LoadLibrary('/home/bryce/Programming/opencompile/libvollib.so')
dbhob = c_float(42.2)
vol = (c_float * 15)()
voleqi = c_char_p("101DVEW119 ")
mylib.ezvollib_(voleqi, dbhob, vol)
这样运行没有分段错误,但似乎没有#34;填充"变量vol
,带有所需的15个浮点值。
有没有办法让vol
检索从EZVOLLIB
函数返回的值?
答案 0 :(得分:0)
这里有许多类似的问题,但很难找到完全重复。有几种可能的方法可以实现不同程度的通用正确性和可移植性。
最正确的方法是使用现代Fortran到C的互操作性,如fortran77, iso_c_binding and c string中所述,这需要编写更多的Fortran包装代码。
有些人严格禁止写Fortran,尽管这是唯一的便携式解决方案。在这种情况下,他们必须探索编译器中Fortran字符串的实际调用约定。通常,带有字符串长度的隐藏整数参数将传递给子例程。对于gfortran,请参阅https://gcc.gnu.org/onlinedocs/gfortran/Argument-passing-conventions.html
您的ctypes
接口可以使用这些特定于编译器的调用约定,但接口将是编译器特定的。但是您已经依赖于特定名称mangling ezvollib_
,这也是特定于编译器的。你可以在这里找到关于人们因依赖它而被咬伤的例子。
另请注意,正如High Performance Mark所指出的那样,所讨论的子程序有四个参数,而不是三个:EZVOLLIB(VOLEQI,DBHOB,HTTOT,VOL)
。如mylib.ezvollib_(voleqi, dbhob, vol)
中那样仅使用三个调用它是一个错误。您缺少HTTOT
参数。