C++调用Fortran编写的DLL时对可变数组的应对方法

C++调用Fortran编写的DLL时对可变数组的应对方法

由于C++程序本身在语言的通用性上有着巨大的优势,常常会用来进行底层或框架的编程,而Fortran由于其强大的矩阵计算功能,程序员或者科研工作者常常拿来进行算法上的编写,这中间就产生了他们之间参数传递的问题。本文就个人经验对C++调用Fortran编写的动态链接库中遇到可变数组时如何处理进行总结,以期更好的掌握混编的强大功能。

1. C++调用Fortran时的规则

C++在调用Fortran的DLL库时,一般可以采用显示链接,对调用约定进行设定,如果调用约定没有事先说清,会产生参数传递不对的情况。Fortran默认的调用约定是_stdcall方式,而C++默认的调用约定是_cdecl方式,所以这两者要选择一个进行调整,统一到一种约定上来。这里我们选择调整C++来进行调整,主要是因为C++语言更加自由,可选择性高。
显式调用的步骤分为以下几步:

  1. 加载dll
#include<window.h>
HMODULE h=LoadLibrary(L"xxx.dll");
  1. 获取函数地址
typedef void(*FUNC)(double* x,  int* y,  double z[200],  double* A)
  1. 利用函数指针调用函数
FUNC func=(FUNC)GetProcAddress(h,"func");
  1. 释放dll
FreeLibrary(h);

上面是显式动态链接库加载的一般方式,但是正如开头讲的,由于Fortran和C++默认调用约定不同,这里要进行设置,在第2步时,需如下写

typedef void(_stdcall* FUNC)(double* x,  int* y,  double z[200],  double* A);

可以看到本行增加了对调用约定的设置。
本处的具体知识可以参考黄强老师的视频教程
C++动态链接库视频教程(Windows动态链接库)

2. 参数传递的要求

C++在调用Fortran的动态链接库时,默认的方式是地址传递,所以上面的第2步进行函数地址传递时,采用的均是指针变量形式,包括z[200]实际上也是传递的数组地址。
对于可变数组,C++一般是需要进行new操作,及以下操作:

int Num_A = y;
double* A = new double[Num_A];

这样就可以建立一个动态的数组A,数组大小可以通过Num_A来进行设定。那么在Fortran中,如何进行设定呢?

subroutine FUNC(x , y , z , A)
implicit none
!DEC$ ATTRIBUTES DLLEXPORT :: FUNC
real(8),	    intent(in)    	:: x
integer(4),intent(in)    	:: y
real(8),    intent(out)   	:: z(200)
real(8)							::	A(y)

...

end subroutine FUNC

可以看到A(y)对可变的数组A进行了定义,这样就可以和C++中的可变数组进行同步。

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值