在 C++/FORTRAN 互操作中处理字符串的官方方法是什么
What is the official way to deal with string in C++/FORTRAN interop
我想了解 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 提出问题后,我进一步调查了这个问题。基本上,"assumed size" 字符数组不是必需的1,虽然我确实相信 char 数组的大小是(请更正我,如果我错了)。我将 post 下面的 C 调用 Fortran 版本,因为我不知道 C++ 语法并且不想查找它。
编辑 2
如脚注 1 中所述,在 Fortran 程序中将 people
声明为假定大小的字符数组或(如@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更新:好像官方的用法"for interoperability"是声明为一个数组字符,使用假定大小:char(len=1,kind=c_char), dimension(*), intent(in)
我想了解 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 提出问题后,我进一步调查了这个问题。基本上,"assumed size" 字符数组不是必需的1,虽然我确实相信 char 数组的大小是(请更正我,如果我错了)。我将 post 下面的 C 调用 Fortran 版本,因为我不知道 C++ 语法并且不想查找它。
编辑 2
如脚注 1 中所述,在 Fortran 程序中将 people
声明为假定大小的字符数组或(如@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更新:好像官方的用法"for interoperability"是声明为一个数组字符,使用假定大小:char(len=1,kind=c_char), dimension(*), intent(in)