Stupid && 祖传Fortran代码救赎之路(编译Dll)

gfortran编译动态库

在Windows平台下,Intel Fortran安装过于庞大且费事(现在集成到OneAPI上了,安装下需要60G),之前在VS2019上折腾了好久,最后Debug调试不显示过程变量,吐了。。。

后来决定直接用gfortran+gdb+VScode来做Fortran程序的调试与编译。在此记录一下,如何时使用gfortran编译Dll,以及如何使用C++、Matlab调用Fortran生成的Dll库。

Fortran测试程序(test.f90)

各种不同的Fortran源程序定义接口的方法看到过不少,比如传送门

最后发现以下这种方式最为简单,且有效,具体为啥我也不清楚。

测试程序中test1()没有输入输出,test2(array,Num)需要返回一个数组(Fortran函数大都需要数组作为输入输出)。

subroutine test1() BIND(C,NAME="test1")
implicit none
PRINT *, 'I am a function'
return
end subroutine test2(array,Num) BIND(C,NAME="test2")
implicit none
INTEGER,INTENT(IN):: Num
REAL*8,INTENT(OUT):: array(1:Num)
INTEGER :: I
DO I=1,Num
array(I)=I
ENDDO
end

编译命令

编译成为动态库

> gfortran -c -O3 f90
> gfortran -shared -static -o Test.dll *.o

编译完成即可得到名为\(Test.dll\)的动态链接库

C++调用Fortran动态库(DLL)

采用显示调用的方式调用动态库,在Windows平台下,借助\(Windows.h\)中的\(LoadLibrary,GetProcAddress,FreeLibrary\)动态加载,使用动态库。

测试程序

#include <iostream>
#include <Windows.h> using namespace std;
typedef void(*test1Func)();
typedef void(*test2Func)(double*, int*); int main(void)
{
//加载DLL库
HINSTANCE hDLL = LoadLibrary(L"Test.dll");
//定义函数指针
test1Func test1; // Function pointer
test2Func test2; if (hDLL != NULL)
{
//获得函数地址
test1 = (test1Func)GetProcAddress(hDLL, "test1");
test2 = (test2Func)GetProcAddress(hDLL, "test2"); if (!test1 && !test2)
{
// handle the error
std::cout << "Open the dll error" << std::endl;
//卸载函数库
FreeLibrary(hDLL);
return -1;
}
else
{
test1();
int Num = 10;
double* myarray = new double[Num];
test2(myarray, &Num);
for (int i = 0; i < Num; ++i)
cout << myarray[i] << endl;
FreeLibrary(hDLL);
}
}
return 0;
}

输出

 I am a function
1
2
3
4
5
6
7
8
9
10

Matlab 调用.DLL

现在已经得到gFortran编译的Dll库,在Matlab中,可以使用calllib方法调用函数,但是需要存在函数声明,所以首先编写C头文件,存放函数声明。

函数声明头文件

//Test.h
void test1();
void test2(double*,int * );

Matlab Demo

clc;clear all;
loadlibrary('Test.dll','Test.h');
% test1 函数没有参数,也没有返回值,不知道咋调用
% calllib('Test','test1');
Num=10;
myarray=zeros(Num,1);
[myarray,NN]=calllib('Test','test2',myarray,Num);
myarray
NN
unloadlibrary Test

输出结果

myarray =

     1
2
3
4
5
6
7
8
9
10 NN = int32 10

参考链接

Windows下gfortran编译DLL

Windows下安装InterFortran

Matlab调用Fortran编译的DLL

最新文章

  1. 一种简单的md5加盐加密的方法(防止彩虹表撞库)
  2. DSP using MATLAB 示例Example2.4
  3. rtl8723 2个 wlan
  4. python中使用多继承
  5. 20151007kaggle Titanic心得
  6. C/C++编译预处理命令详解【转】
  7. TestNG Listener
  8. php这样实现伪静态
  9. leetcode Linked List Cycle python
  10. 面试中关于Java中涉及到知识点(转)
  11. java中取得上下文路径的方法
  12. 用惯了Task,你应该也需要了解它的内部调度机制TaskScheduler
  13. (数字IC)低功耗设计入门(二)——功耗的分析
  14. 【2017-06-05】Jquery.ajax
  15. eclipse中Cannot change version of project facet Dynamic Web Module to 2.5.
  16. CCRenderBuffer初始化中的render state参数
  17. oracle 关于房贷计算过程
  18. .Net调用Java带验证的WebService解决方法
  19. mysql大表设计以及优化
  20. 说说Android6.0动态申请权限的那些坑

热门文章

  1. PAT (Basic Level) Practice (中文)1007 素数对猜想 (20分)
  2. perl 不支持多条件比较
  3. OO第三次博客作业--第三单元总结
  4. Seata分布式事务失败通知
  5. 如何清理history
  6. Python课程笔记(十)
  7. 你知道怎么从jar包里获取一个文件的内容吗
  8. 反转单词顺序列 牛客网 剑指Offer
  9. Python技法4:闭包
  10. 微信公众号H5跳转小程序