栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++与Fortran动态链接库之间的数据传递

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++与Fortran动态链接库之间的数据传递

前一篇文章讨论了C++程序对Fortran动态链接库中的函数调用,其数据交换主要在Fortran程序之间,而没有出现在两种语言之间。本文进一步探讨C++与Fortran动态链接库之间的数据交换。

数据交换有多种方式,例如通过函数的参数传递、指针、全局变量等等。C++与Fortran这两种语言之间一般变量(变量或数组等)的数据传递比较容易,但自定义数据类型的数据交换则略显困难,主要是因为两种语言对于自定义数据类型的内存管理方式存在差异。示例如下:

一、Fortran90 程序

MODULE EXAMP_MOD
USE, INTRINSIC ::  ISO_C_BINDING
IMPLICIT NONE
!两个自定义类型
TYPE,BIND(C) :: EXAMP1_TYPE
   REAL(C_FLOAT)  :: A
   INTEGER(C_INT) :: I1
   INTEGER(C_INT) :: I2
END TYPE EXAMP1_TYPE

TYPE,BIND(C) :: EXAMP2_TYPE
   REAL(C_FLOAT)  :: AA
   INTEGER(C_INT) :: II1, II2
END TYPE EXAMP2_TYPE

!函数接口可以不要
!interface
!
!subroutine FSUB(EXAMP,COMMON_EXAMP,INT_ARG, STR_IN, STR_OUT) bind(C,name='FSUB')
!use examp_mod
!implicit none
!type(EXAMP1_TYPE) :: EXAMP
!type(EXAMP2_TYPE) :: COMMON_EXAMP
!INTEGER :: INT_ARG
!CHARACTER,dimension(*):: STR_IN
!CHARACTER,dimension(*) :: STR_OUT
!end subroutine FSUB
!
!end interface

END MODULE EXAMP_MOD

在Fortran中,通过module定义了两个自定义数据类型,将这两个类型定义的变量通过函数参数,实现了C++与Fortran之间的传递。

!通过参数传递这两个自定义类型的变量
SUBROUTINE FSUB(EXAMP,COMMON_EXAMP,INT_ARG, STR_IN, STR_OUT) !BIND(C,NAME='FSUB') 
!如果绑定,反而对字符参数传递有影响,因为fortran当中是字符串,而C++是字符数组
!DEC$ ATTRIBUTES DLLEXPORT::FSUB
USE EXAMP_MOD
IMPLICIT NONE

TYPE(EXAMP1_TYPE) :: EXAMP !
!DEC$ ATTRIBUTES DLLEXPORT :: vEXAMP!

TYPE(EXAMP2_TYPE) :: COMMON_EXAMP !
!DEC$ ATTRIBUTES DLLEXPORT :: vCOMMON_EXAMP!

INTEGER, INTENT(IN) :: INT_ARG !如果绑定应该使用INTEGER(C_INT)
CHARACTER(*), INTENT(IN) :: STR_IN !如果绑定应该使用CHARACTER(C_CHAR)
CHARACTER(*), INTENT(OUT) :: STR_OUT !如果绑定应该使用CHARACTER(C_CHAR)
CHARACTER*5 INT_STR
WRITE (INT_STR,'(I5.5)')INT_ARG !将整型数转换成字符串
EXAMP%A  = 12.
EXAMP%I1 = 22
EXAMP%I2 = 33
COMMON_EXAMP%AA  = 13.
COMMON_EXAMP%II1 = 24
COMMON_EXAMP%II2 = 34
STR_OUT = STR_IN // INT_STR // CHAr(0) !合并字符串,如果绑定此处STR_OUT = STR_IN
RETURN
END subroutine FSUB

二、C++程序

#include 
#include 
#include 
#include 

// 与Fortran对应的两个自定义类型
typedef struct EXAMP1_TYPE{
    float A;
    int I1;
    int I2;
}EXAMP;

typedef struct EXAMP2_TYPE{
    float AA;
    int II1;
    int II2;
}COMMON_EXAMP;

extern "C" void _cdecl FSUB (EXAMP *vEXAMP1,          //也可使用&vEXAMP1
                      COMMON_EXAMP *vCOMMON_EXAMP1,   //也可使用&vCOMMON_EXAMP1
                               int *INT_ARG,          //也可使用&INT_ARG
                              char *STR_IN,
                              char *STR_OUT,
                            size_t  STR_IN_LEN,
                            size_t  STR_OUT_LEN);

在C++中,首先也要定义两个与Fortran对应的数据类型,同时申明外部函数,需要注意函数声明中变量的写法。

void main (int argc, char *argv[]) 
{
// declaration 
char instring[40];
char outstring[40];
int intarg;

EXAMP vEXAMP;
COMMON_EXAMP vCOMMON_EXAMP;

// initializing 

strcpy_s(instring,"Testing...");
intarg = 123;
vEXAMP.A = 0.;
vEXAMP.I1 = 0;
vEXAMP.I2 = 0;
vCOMMON_EXAMP.AA = 0.;
vCOMMON_EXAMP.II1 = 0;
vCOMMON_EXAMP.II2 = 0;



FSUB(&vEXAMP,&vCOMMON_EXAMP,&intarg,instring,outstring,strlen(instring),sizeof(outstring));
//若外部函数声明中使用了取地址符&,此处则应使用EXAMP,COMMON_EXAMP,intarg

printf(" %f  %i  %i  %f  %i  %in", vEXAMP.A, vEXAMP.I1, vEXAMP.I2, vCOMMON_EXAMP.AA, vCOMMON_EXAMP.II1, vCOMMON_EXAMP.II2);

vEXAMP.A = 0.;
vEXAMP.I1 = 0;
vEXAMP.I2 = 0;
vCOMMON_EXAMP.AA = 0.;
vCOMMON_EXAMP.II1 = 0;
vCOMMON_EXAMP.II2 = 0;

printf(" %f  %i  %i  %f  %i  %in", vEXAMP.A, vEXAMP.I1, vEXAMP.I2, vCOMMON_EXAMP.AA, vCOMMON_EXAMP.II1, vCOMMON_EXAMP.II2);
printf("%sn",outstring);

system("pause");

} 

通过地址或值传递都可以实现两种语言之间的数据交换。程序运行结果如下:

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/869840.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号