在C ++ / FORTRAN interop中处理字符串的官方方式是什么? [英] What is the official way to deal with string in C++/FORTRAN interop

查看:114
本文介绍了在C ++ / FORTRAN interop中处理字符串的官方方式是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想特别学习C ++ / FORTRAN互操作性方面的最新进展。以下是我不成功的尝试,请帮助我纠正或提供更好的解决方案。
我的编译器是gcc 4.8.5



在C ++中

  #include< iostream> 

externC{
void SayHello(char *);
}
int main(int argc,char ** argv){
char * name = argv [1];
SayHello(姓名);
返回0;
}

在Fortran中

  module MyModule 

包含
子例程SayHello(people)bind(c,name =SayHello)
use,intrinsic :: iso_c_binding
character,dimension(50),intent(in):: people
write(*,*)Hello,people
结束子程序
结束模块MyModule


解决方案

尝试使用 c_char type:



character(kind = c_char),dimension(*),intent(in) p>




编辑1
所以,在@francescalus提出问题之后,进一步。基本上,假定大小字符数组并不是必需的,尽管我相信char数组的大小是(请纠正我,如果我错了那)。我将在下面发布一个C调用Fortran版本,因为我不知道C ++语法,并且不想查找它。






编辑2
如脚注1所述,只需在 people
中声明Fortran程序作为假定的字符大小数组,或者(由@VladimirF建议),其大小直接由 sz 给出。我在下面的代码中清楚了这一点。



Fortran程序:

 ! SayHello.f90 
子程序SayHello(people,sz)bind(c,name =SayHello)
use,intrinsic :: iso_c_binding
implicit none
!注意:
!字符数组的大小`sz`通过值传入。
!为了正确性声明`people`为假定大小的数组,或者只是使用从C.b $ b字符(kind = c_char),intent(in),dimension(sz):: people $中传入的大小`sz` b $ b integer(kind = c_int),intent(in),value :: sz
write(*,*)Hello,people(1:sz)
结束子程序

和C程序:

  / * Hello.c * / 
#include
#include< string.h>
#include< stdlib.h>

void SayHello(char * name,int len);
$ b $ int main(int argc,char ** argv){
size_t sz = strlen(argv [1]);
char * name = malloc(sz + 1);
strcpy(name,argv [1]);
SayHello(姓名,sz + 1);
free(name);
返回0;

$ / code>

编译(使用ifort),调用和输出:

  ifort / c SayHello.f90 
icl Hello.c / link SayHello.obj
Hello.exe MattP
//输出:您好,MattP

1 更新:看起来像互用性的官方用法是使用假定的大小声明为一个字符数组: char(len = 1,kind = c_char),dimension(*), intent(in)


I'd like to learn the latest improvement in C++/FORTRAN interoperability when it comes to string in particular. The following is my unsuccessful attempt, please help me correct or advise a better solution. My compiler is gcc 4.8.5

In C++

#include <iostream>

extern "C"{
    void SayHello(char*);
}
int main(int argc, char** argv){
    char * name = argv[1];
    SayHello(name);
    return 0;
}

In 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

解决方案

Try using the c_char type:

character(kind=c_char), dimension(*), intent(in)


EDIT 1 So, after @francescalus posed the question, I looked into this further. Basically, the "assumed size" character array is not necessary1, although I do believe that the size of the char array is (please correct me if I'm wrong about that). I'm going to post a C-calling-Fortran version below, since I don't know the C++ syntax and don't feel like looking it up.


EDIT 2 As mentioned in footnote 1, it is only correct to declare people in the Fortran program as an assumed size array of chars, or (as suggested by @VladimirF) with the size given directly by sz. I clear this up in the code below.

The Fortran program:

! 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

And the C program:

/*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;
}

Compilation (with ifort), call, and output:

ifort /c SayHello.f90 
icl Hello.c /link SayHello.obj
Hello.exe MattP
// output: Hello, MattP

1Update: Seems like the official usage "for interoperability" is to declare as an array of characters, using assumed size: char(len=1,kind=c_char), dimension(*), intent(in)

这篇关于在C ++ / FORTRAN interop中处理字符串的官方方式是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆