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

Stupid && 祖传Fortran代码救赎之路(编译Dll)的更多相关文章

  1. Snippet Compiler——代码段编译工具

    原文地址:http://www.cnblogs.com/conexpress/archive/2011/07/24/2115308.html 不知道大家在工作中是否遇到过下面的情况:在项目中实现了一段 ...

  2. .NET代码自动编译发布

    .NET代码自动编译发布   因本人一直使用.NET开发,在做项目的时候,每次都要涉及到各个环境的部署问题,手工操作容易出错,并且重复劳动多,所以一直在寻找一个能实现自动化部署的方案. 废话不多讲,先 ...

  3. Android源码树中C代码的编译

    侯 Sir说:“源码之下,了无秘密.” 但有些秘密还是要搞起来了看得更真切,仅从静态代码的体位很难体会到运动时的妙处.因此环境搭好了,下一步就是调试.gdbserver搭配gdb的调试环境走得很顺利, ...

  4. MinGW编译dll并引用

    记得某位神仙曾经说过:一个项目不使用dll简直是一场灾难.(滑稽) 这篇文章以A+B/A-B为范例,来介绍如何在MinGW下编译dll并引用. 首先你要安装MinGW,并配置好环境变量(不配置环境变量 ...

  5. codeforces 1424J,为了过这题,我把祖传的C++都用上了!

    大家好,我们选择的是Bubble Cup比赛Div2场次的J题,不用问我Bubble Cup是什么比赛,我也不清楚.总之是一场算法比赛就是了.可能是这个比赛知名度比较低吧,参与的人数也不是很多,我们选 ...

  6. 上传python代码到pypi

    上传python代码到pypi 去pypi官网注册账号 在项目中添加setup.py # coding = utf-8 from setuptools import setup, find_packa ...

  7. Eclipse下使用GDT插件无法登陆GAE & GDT无法上传JAVA代码

    今天更新github主页的过程中,想使用GAE部署一个Java Web服务来更好的支持网站动态性(关键是利用了免费的GAE资源),结果遇到了2个大问题. 1.GDT插件无法登陆GAE账户 错误1:登陆 ...

  8. git上传项目代码到github

    参考: git学习——上传项目代码到github github上传时出现error: src refspec master does not match any解决办法 git 上传本地文件到gith ...

  9. [html5+java]文件异步读取及上传核心代码

    html5+java 文件异步读取及上传关键代码段 功能: 1.多文件文件拖拽上传,file input 多文件选择 2.html5 File Api 异步FormData,blob上传,图片显示 3 ...

随机推荐

  1. XiaoXin 13Pro-Hackintosh 小新13pro崇尚极简的黑苹果双系统

    Lenovo XiaoXin-13-Pro-Hackintosh 关键词:Hackintosh XiaoXin EFI Tutorial Lenovo 以下提及的EFI及其他部分文件见github仓库 ...

  2. Vue2源码解读 - 响应式原理及简单实现

    直接进入主题了,想必大家都知道实现vue响应式核心方法就是 Object.defineProperty,那就从它开始说 Object.defineProperty 缺点: 深度监听,需要递归到底,一次 ...

  3. 整理一下在 npmjs.com 上面发布资源包踩过的坑

    正常流程就不说了,网上有很多,比如写代码.打包.注册.登录.发布等. 邮箱要激活 在 npmjs.com 上面注册账号的时候需要填写邮箱,然后登录网址的时候并没有强制要求你去邮箱激活. 但是到了发布资 ...

  4. Coursera Deep Learning笔记 结构化机器学习项目 (上)

    参考:https://blog.csdn.net/red_stone1/article/details/78519599 1. 正交化(Orthogonalization) 机器学习中有许多参数.超参 ...

  5. Java:NIO 学习笔记-2

    Java:NIO 学习笔记-2 上一篇 NIO 学习笔记-1 看了 尚硅谷 的相应教程,此处又对比看了 黑马程序员 的课程 JAVA通信架构I/O模式,做了相应的笔记 前言 在 Java 的软件设计开 ...

  6. 第七次Alpha Scrum Meeting

    本次会议为Alpha阶段第六次Scrum Meeting会议 会议概要 会议时间:2021年5月4日 会议地点:线上会议 会议时长:20min 会议内容简介:本次会议主要由每个人展示自己目前完成的工作 ...

  7. AIApe问答机器人Scrum Meeting 4.27

    Scrum Meeting 3 日期:2021年4月27日 会议主要内容概述:汇报两日工作. 一.进度情况 组员 负责 两日内已完成的工作 后两日计划完成的工作 工作中遇到的困难 李明昕 后端 Tas ...

  8. 2021.8.17考试总结[NOIP42]

    $\huge{取模不能比大小!}$ $\huge{取模不能比大小!}$ $\huge{取模不能比大小!}$ 有了打地鼠的前车之鉴,我深信树规板子是可以出现在联赛题里的. 所以T1十分钟码完直接溜了,后 ...

  9. 单源最短路径算法:迪杰斯特拉 (Dijkstra) 算法(二)

    一.基于邻接表的Dijkstra算法 如前一篇文章所述,在 Dijkstra 的算法中,维护了两组,一组包含已经包含在最短路径树中的顶点列表,另一组包含尚未包含的顶点.使用邻接表表示,可以使用 BFS ...

  10. 0x04

    二分: while(l<r) { int mid=(l+r)/2; if(符合条件) r=mid; else l=mid+1; } 固定下二分的写法: 终止条件:l==r: 取mid=(l+r) ...