在fortran和c之间传递字符串有问题。
Fortran子例程调用如下所示:
CALL MMEINITWRAPPER(TRIM(ADJUSTL(PRMTOP)), 0, SALTCON, RGBMAX, CUT)
与此相关的C有签名:
int mmeinitwrapper_(char *name,
int *igb,
REAL_T *saltcon,
REAL_T *rgbmax1,
REAL_T *cutoff1)
我把一些打印语句放在不同的地方,一切都很好,直到我用ifort编译。在这种情况下,输出如下:
Topology file name:
coords.prmtop
coords.prmtop
Topology file name length: 81 13
length in C: 8
read argument: coords.prmtop��*
Reading parm file (coords.prmtop��*)
coords.prmtop��*, coords.prmtop��*.Z: does not exist
Cannot read parm file coords.prmtop��*
使用波特兰编译器:
Topology file name:
coords.prmtop
coords.prmtop
Topology file name length: 81 13
length in C: 8
read argument: coords.prmtop
Reading parm file (coords.prmtop)
第一组中的长度来自fortran中未修剪/未调整的字符串,然后是修剪/调整的字符串。c中的长度来自
sizeof(name)/sizeof(name[0])
。它似乎传递了一段太长的内存,在随后的运行中,您会收到不同长度的错误内容(尽管C中报告的长度总是8)。
有人有什么想法吗?很难让gdb与fortran/c结合使用。
最佳答案
我相信你要找的答案是:
Arrays of strings in fortran-C bridges using iso_c_binding
基本上,fortran“知道”字符串的长度,但不知道c的长度,所以您必须通过将fortran长度传输到c,然后在c代码中做出适当的反应,以某种方式让c代码知道。
下面的问题将从“纯”Fortran POV中探讨此问题,并对给出的各种答案进行深入了解:
Fortran to C , effect of trim on space allocated to string
并且要记住,编译器可能会利用一些未定义或特定于实现的差异来解释观察到的各种行为。
另外,我刚刚意识到,假设sizeof
给出字符串的大小是错误的。它给出了指针的大小。因此sizeof(name)/sizeof(name[0])
是一个常数,表示achar
的大小,而asizeof(name)
本身是c中8字节的常数。sizeof(name[0])
表示字符指针的大小,表示字符的大小。结果是常数8。