【问题标题】:Passing strings to Fortran subroutine using ctypes使用 ctypes 将字符串传递给 Fortran 子例程
【发布时间】:2017-12-05 22:45:23
【问题描述】:

我目前正在尝试将字符串传递给 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)

这在没有分段错误的情况下运行,但似乎没有用所需的 15 个浮点值“填充”变量 vol

有没有办法让vol 检索从EZVOLLIB 函数返回的值?

【问题讨论】:

  • 什么 15 个浮点值?
  • 函数需要三个参数 ... EZVOLLIB(VOLEQI,DBHOB,HTTOT,VOL) ??

标签: python fortran ctypes


【解决方案1】:

这里有很多类似的问题,但很难找到一个准确重复的问题。有几种可能的方法可以实现不同程度的通用正确性和可移植性。

最正确的方法是使用现代 Fortran 到 C 的互操作性,如 fortran77, iso_c_binding and c string 中所述,这需要编写更多的 Fortran 包装代码。

有些人严格反对再编写 Fortran,尽管这是唯一可移植的解决方案。在这种情况下,他们必须探索编译器中 Fortran 字符串的实际调用约定。通常将带有字符串长度的隐藏整数参数传递给子例程。对于 gfortran,请参阅 https://gcc.gnu.org/onlinedocs/gfortran/Argument-passing-conventions.html

您的ctypes 接口可以使用这些特定于编译器的调用约定,但是该接口将是特定于编译器的。但是您已经依赖于特定名称修饰ezvollib_,这也是特定于编译器的。您可以在 SO 上找到人们因依赖它而被咬伤的示例。

还请注意,正如 High Performance Mark 所指出的,所讨论的子例程有四个参数,而不是三个:EZVOLLIB(VOLEQI,DBHOB,HTTOT,VOL)。在mylib.ezvollib_(voleqi, dbhob, vol) 中只用三个调用它是一个错误。您缺少 HTTOT 参数。

【讨论】:

    猜你喜欢
    • 2017-07-08
    • 1970-01-01
    • 2017-06-11
    • 2021-04-27
    • 1970-01-01
    • 2011-11-11
    • 2015-02-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多