Stupid && 祖传Fortran代码救赎之路(编译Dll)
2021-12-01 14:07
78 查看
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 -fPIC -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
参考链接
相关文章推荐
- 已安全化的ActiveX控件卸载时出现"DllUnregisterServer函数出错,错误代码:0x80070002"问题解决
- 【IDE-Visual Studio】编译出错(chenlu-3):无法打开文件“some.exe”\"some.dll"
- 引用dll 写代码没问题,编译出问题
- 使用SNK密钥文件保护你的DLL和代码不被反编译教程
- unity 安卓热更新代码的最新方法: 通过Mono加载新的重新编译的dll
- 工欲善其事,必先利其器 软件工具开发关键词 protractor自动化测试工具 RegexBuddy正则 CodeSmith,LightSwitch:代码生成 CheatEngine:玩游戏修改内存值必备神器 ApkIDE:Android反编译工具 Reflector:反编译dll动态链接库
- 模块"jscript.dll"已加载,但对DllRegisterServer的调用失败,错误代码为0x8000。。。
- 编译2010年x264最新的代码供VC编译使用DLL与LIB
- ubuntu下 GCC编译程序出现 undefined reference to `std::ios_base::Init::Init()'问题——gcc编译C++代码
- 把一些重要的代码编译成Lib或者dll
- mingw编译x264 dll时出现 "make[1]: lib: Command not found"的解决方法
- ASP.Net一键自动化更新代码、编译、合并dll、压缩js、css、混淆dll、zip打包、发布到测试环境的bat批处理
- 动态编译代码,生成dll
- 编译原理课程设计_C--编译器_语法分析&代码生成
- DLL to C: 能把DLL转换成可编译的C代码的工具
- 相同的代码在eclipse中编译成功,但是用ant编译失败。无法确定<T>T的类型参数;对于上限为int,java.lang.Object的类型变量T,不存在唯一最大实例
- Part2. 使用Visual Studio把C代码编译成.dll文件
- ubuntu 12.04编译android代码遇到"_FORTIFY_SOURCE"的解决方法
- 编译原理-词法分析04-NFA & 代码实现
- Cocos2dx 3.6源代码编译错误:syntax error : missing ')' before '{'