我想在尤其是字符串方面学习C /fortran互操作性的最新改进。以下是我失败的尝试,请帮助我纠正或建议更好的解决方案。我的编译器是GCC 4.8.5
在C
中#include <iostream>
extern "C"{
void SayHello(char*);
}
int main(int argc, char** argv){
char * name = argv[1];
SayHello(name);
return 0;
}
fortran
module MyModule
contains
subroutine SayHello(people) bind(c,name="SayHello")
use, intrinsic :: iso_c_binding
character, dimension(50), intent(in) :: people
write(*,*) "Hello ", people
end subroutine
end module MyModule
尝试使用c_char
类型:
character(kind=c_char), dimension(*), intent(in)
编辑1 因此,在@francescalus提出了这个问题之后,我进一步研究了这个问题。基本上,"假设大小"字符阵列不是必需的那(。我将在下面发布一个C-Calling-Fortran版本,因为我不知道C 语法,并且不想查找。
编辑2 如脚注1中所述,只能在Fortran程序中声明people
为假定的chars大小数组,或者(如@vladimirf所建议(,其大小直接由sz
给出。我在下面的代码中清除了这一点。
fortran程序:
! SayHello.f90
subroutine SayHello(people,sz) bind(c,name="SayHello")
use, intrinsic :: iso_c_binding
implicit none
! Notes:
! The size `sz` of the character array is passed in by value.
! Declare `people` as an assumed-size array for correctness, or just use the size `sz` passed in from C.
character(kind=c_char), intent(in), dimension(sz) :: people
integer(kind=c_int), intent(in), value :: sz
write(*,*) "Hello, ", people(1:sz)
end subroutine
和C程序:
/*Hello.c */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void SayHello(char *name, int len);
int main(int argc, char** argv){
size_t sz = strlen(argv[1]);
char * name = malloc(sz+1);
strcpy(name, argv[1]);
SayHello(name, sz+1);
free(name);
return 0;
}
汇编(带有ifort(,呼叫和输出:
ifort /c SayHello.f90
icl Hello.c /link SayHello.obj
Hello.exe MattP
// output: Hello, MattP
1 更新:似乎是官方用法"用于互操作性"是使用假定的大小来声明为字符数组:char(len=1,kind=c_char), dimension(*), intent(in)