我正在使用 c_types 将 fortran 库与 python 连接。我在python中初始化结构,将它们传递给填充它们的fortran,然后在python中读回它们。数字数组一切正常,但现在我被接口字符串数组困住了。
我试过这样的例子,这没问题,但在这种情况下,c_char 数组不在结构中。因此,我尝试修改前面的示例,将 c_char 数组放入结构中。这是我使用的代码,有和没有结构:
Python代码:
from ctypes import *
lib = CDLL("./libf.so")
if 1:
print(">>> Without structure")
func = getattr(lib, "fortran2py_")
nstring = pointer(c_long(2))
carr = (c_char * 255)()
func.argtypes = [POINTER(c_long), POINTER(c_char)]
print(type(carr))
print('before:',carr)
func(nstring, carr)
str1, str2 = ''.join([v.decode("utf-8") for v in carr]).rstrip("\x00").split("\x00")
print(str1, str2)
class Struct0(Structure):
_fields_ = [
("name", c_char * 255),
]
if 1:
print(">>> With structure")
func = getattr(lib, "fortran2pystr_")
nstring = pointer(c_long(2))
carr = Struct0()
func.argtypes = [POINTER(c_long), POINTER(Struct0)]
print(type(carr.name))
print('before:',carr.name)
func(nstring, byref(carr))
print('after:',carr.name)
Fortran 代码:
module c_interop
use iso_c_binding
implicit none
integer, parameter :: STRLEN = 64
type, bind(c) :: charStr
character(c_char) :: name(255)
end type charStr
我没有得到任何错误,除了在修改部分,Fortran 应该填充 c_char carr.name 在 mystr 的元素上循环的数组,但结果字符串只包含第一个元素。当carr不是结构体而是直接c_char数组时,python可以读取mystr的所有内容。
如您所见, carr 和 carr.name 的类型也不相同。您知道我修改后的代码有什么问题吗?谢谢 !
如所见,数据字段类型已更改
我想到的最简单的解决方案是将字符串分隔符从NUL替换为您确定它不会出现在任何字符串中的另一个字符。我选择了0xFF ( 255 )。我认为包含 的结构也可以,但它会更复杂一些(另外,我没有测试它)ctypes.POINTER(ctypes.c_char)
我的Fortran知识非常接近0,但是fortran2pystr看起来不太对劲。我不知道Fortran类型是如何构造的,但是从Python传递一个包装在结构指针中的char数组(实际上,它们具有相同的地址)并像普通char数组一样处理它似乎是错误的。更改struct可能会导致灾难
扬帆大鱼
相关分类