【发布时间】:2014-10-25 22:36:51
【问题描述】:
如何将 C 字符串数组 (char* cstrings[]) 传递给 Fortran
子程序?
问题Arrays of strings in fortran-C bridges using iso_c_binding 肯定是相关的,但答案似乎不正确,甚至无法使用 GNU Fortran 编译。
我目前正在为 Fortran 代码开发 C 接口,我希望 iso_c_binding(我以前使用过)可以让这变得轻而易举。到目前为止,C 字符串数组还没有运气......
Fortran 子例程应将字符串数组作为参数。 在普通的 Fortran 中,我会写如下内容:
subroutine print_fstring_array(fstring)
implicit none
character(len=*), dimension(:), intent(in) :: fstring
integer :: i
do i = 1, size(fstring)
write(*,*) trim(fstring(i))
end do
end subroutine print_fstring_array
将单个 C 字符串传递给 Fortran 的一种方法是作为 C 指针 (c_ptr)(我知道,我也可以使用 character(kind=c_char) 的数组)
subroutine print_cstring(cstring) bind(C)
use iso_c_binding, only: c_ptr, c_f_pointer, c_loc, c_null_char
implicit none
type(c_ptr), target, intent(in) :: cstring
character(len=1024), pointer :: fstring
integer :: slen
call c_f_pointer(c_loc(cstring), fstring)
slen = index(fstring, c_null_char) - 1
write(*,*) fstring(1:slen)
end subroutine print_cstring
所以,我认为c_ptr 的数组是个好主意
subroutine print_cstring_array(n, cstring) bind(C)
use iso_c_binding, only: c_ptr, c_int, c_f_pointer, c_loc, c_null_char
implicit none
integer(kind=c_int), intent(in) :: n
type(c_ptr), dimension(n), target, intent(in) :: cstring
character(len=1024), pointer :: fstr
integer :: slen, i
do i = 1, n
call c_f_pointer(c_loc(cstring(i)), fstring)
slen = index(fstring, c_null_char) - 1
write(*,*) fstring(1:slen)
end do
end subroutine print_cstring_array
但这会产生分段错误。
最后一个例子的C代码是
# include "stdio.h"
# include "fstring.h"
void main(void) {
char* cstring[] = { "abc", "def", "ghi", "jkl" };
int n = 4;
print_cstring_array(&n, cstring);
}
而头文件fstring.h的内容很简单:
void print_cstring_array(int* n, char* cstring[]);
我的目标是 GNU Fortran 和 Intel Fortran,并已使用 GNU Fortran 测试了上述内容。 字符串的长度是固定的(上例中为 3),以防这简化了解决方案。但是,数组的维度可以变化。
任何指针(甚至 C 指针)都将不胜感激。
【问题讨论】:
-
请注意:
char* cstrings[]是一个 pointer 指向“字符串”的数组,它不一定指向一个连续的内存块。看看这里:stackoverflow.com/q/13869528/694576 并注意“字符串”数组的定义方式不同。 -
谢谢@alk。这可能是这里的问题。我的C技能不是很好。我怎样才能让它连续?
-
"我如何让它连续?" 就像我链接的问题中的代码那样做。
-
此类问题的谷歌关键字是“混合语言编程”。
-
感谢@alk,您最初的评论中没有该链接。事实上,这个答案看起来很有希望。现在我正在努力掌握细节。
标签: c string fortran fortran-iso-c-binding