【混合编程】C/C++调用Fortran的DLL
【混合编程】C/C++调用Fortran的DLL
以一个简单的加法器为例,介绍C/C++调用Fortran语言DLL的操作过程
一、Fortran操作
1.1 Fortran代码
首先是加法功能的实现,如下代码
!函数功能 两数相加
SUBROUTINE Summator(a,b,c)
REAL a
REAL b
REAL c
c=a+b
END
这是一般在fortran环境下运行的常规格式,为了生成dll,并且被C/C++调用,对以上代码进行编辑修改
!函数功能 两数相加
SUBROUTINE Summator(a,b,c)
!DEC$ATTRIBUTES DLLEXPORT::SUMMATOR
REAL a[VALUE] !此处[VALUE]是必须的,传入的参数值需作此声明,否则会引发读取访问权限冲突的异常
REAL b[VALUE]
REAL c
c=a+b
END
其中
!DEC$ATTRIBUTES DLLEXPORT::SUMMATOR
也可用以下形式替换
!MS$IF.NOT.DEFINED(LINKDIRECT)
!MS$ATTRIBUTES DLLEXPORT::SUMMATOR
!MS$ENDIF
1.2 Dll工程文件建立
使用VS软件,可以通过【文件】->【新建】建立DLL框架:

在新项目下将编辑好的代码添加,编译链接得到 TESTFOR.dll文件。
二、C / C++调用
调用方式有3种,此处只介绍其中一种显示调用方法,其他方式可参照链接
(7条消息) 【混合编程实例】C/C++调用FORTRAN编写的DLL_fengyhack的博客-CSDN博客
首先需要将第一步生成的 .dll 文件Copy到当前C++所在工程目录下,并对函数进行声明
#include<iostream>
#include <windows.h>
using namespace std;
typedef void(*SUMMATOR)(float a, float b, float *c);
在C++工程文件中进行调用
int main(){
//第一步,加载fortran下生成的dll文件
HINSTANCE hLibrary = LoadLibrary(TEXT("TESTFOR.dll"));
//判断是否加载成功
if (hLibrary == NULL) {
cout << "Cannot open lib" << endl;
system("pause");
return -1;
}
//第二步,从加载的结果 hLibrary 中查找函数并命名
SUMMATOR summator = (SUMMATOR)GetProcAddress(hLibrary, "SUMMATOR");
//判断是否查找到函数
if (summator == NULL) {
cout << "Cannot find 'SUMMATOR' function" << endl;
system("pause");
return -2;
}
//第三步,调用
float a = 1.0;
float b = 2.0;
float c = 0.0;
summator(a,b,&c); //调用函数
cout << c << endl; //输出计算的c
FreeLibrary(hLibrary); //释放Library
system("pause");
return 0;
}
三、完整代码
3.1 Fortran代码部分
!函数功能 两数相加
SUBROUTINE Summator(a,b,c)
!MS$IF.NOT.DEFINED(LINKDIRECT)
!MS$ATTRIBUTES DLLEXPORT::SUMMATOR
!MS$ENDIF
REAL a[VALUE]
REAL b[VALUE]
REAL c
c=a+b
END
!函数功能 两个数组相加
SUBROUTINE SummatorArray(array1,array2,array3,n)
!MS$IF.NOT.DEFINED(LINKDIRECT)
!MS$ATTRIBUTES DLLEXPORT::SUMMATORArray
!MS$ENDIF
INTEGER n[VALUE]
INTEGER i
REAL,DIMENSION(n)::array1
REAL,DIMENSION(n)::array2
REAL,DIMENSION(n)::array3
do i=1,n
array3(i)=array1(i)+array2(i)
end do
END
3.2 C代码
#include<iostream>
#include<windows.h>
using namespace std;
typedef void(*SUMMATOR)(float a, float b, float *c);
typedef void(*SUMMATORARRAY)(float *array1, float *array2, float *array3,int n);
int main() {
//加载dll函数
HINSTANCE hLibrary = LoadLibrary(TEXT("TESTFOR.dll"));
if (hLibrary == NULL) {
cout << "Cannot open dll" << endl;
system("pause");
return -1;
}
SUMMATOR summator = (SUMMATOR)GetProcAddress(hLibrary, "SUMMATOR");
if (summator == NULL) {
cout << "Cannot find 'SUMMATOR' function" << endl;
system("pause");
return -2;
}
float a = 1.0;
float b = 2.0;
float c = 0.0;
summator(a,b,&c);
cout << c << endl;
SUMMATORARRAY summatorArray = (SUMMATORARRAY)GetProcAddress(hLibrary, "SUMMATORARRAY");
if (summatorArray == NULL) {
cout << "Cannot find 'SUMMATORARRAY' function" << endl;
system("pause");
return -2;
}
int n = 3;
float *array1 = (float*)calloc(n, sizeof(float));
float *array2 = (float*)calloc(n, sizeof(float));
float *array3 = (float*)calloc(n, sizeof(float));
for (int i = 0; i < n; i++) {
array1[i] = i;
array2[i] = i * i;
}
summatorArray(array1, array2, array3, n);
for (int i = 0; i < n; i++) {
cout << array1[i]<<"+"<<array2[i]<<"="<< array3[i]<<endl;
}
FreeLibrary(hLibrary);
free(array1);
free(array2);
free(array3);
system("pause");
return 0;
}
运行结果

【混合编程】C/C++调用Fortran的DLL的更多相关文章
- [转载:]C#与Fortran混合编程之本地调用Fortran动态链接库
前言 C#发展到现在,已是一门相当完善的语言,他基于C语言风格,演化于C++.并依靠强大的.NET底层框架.C#可以用来快速构建桌面及Web应用.然而在我们的实际工作中,尽管C#已经非常完善,但还是不 ...
- Matlab与C++混合编程 1--在C++中调用自己写的matlab函数
在Visual Studio中使用C++中调用MATLAB程序 在matlab中可以通过mbuild工具将.m文件编译成dll文件供外部的C++程序调用,这样就可以实现matlab和C++混合编程的目 ...
- 【调试经验】C++和C的混合编程以及库调用
问题背景 这两天在移植一个开源的库,偏底层的那种,所以对架构有一些依赖.源码的编译是通过Makefile来构建,怎奈公司的架构用的是CMAKE,所以就在开源的顶层和子目录分别构建了CMakeList, ...
- python c++ 混合编程中python调用c++string返回类型的函数,python中返回为数字的解决办法
本随笔解决 Python使用ctypes 调用c++dll 字符串返回类型函数,在python中显示为数字:原文解决方案见so: https://stackoverflow.com/questions ...
- C#调用Fortran生成的DLL的方法报内存不足
最近在研究一个程序,公司给的,程序是VB写的,程序里面还有一个计算的模型,用Fortran语言写的. 在调试到这个模型里面的方法时报错,说是内存不足,于是就在网上查找方法,看了两篇博客之后问题解决了. ...
- Fortran与C混合编程(转自Ubuntu)
Fortran与C混合编程 由于 GNU 的 Fortran 和 C 语言二者的函数彼此可以直接相互调用,所以混合编程可以非常容易地实现.只要你足够仔细,确保函数调用时传递的参数类型正确,函数就可以在 ...
- 【原创】Matlab.NET混合编程技巧之直接调用Matlab内置函数
本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新 Matlab和C#混合编程文章目录 :[目录]Matlab和C#混合编程文章目录 在我的上一篇文章[ ...
- matlab和C/C++混合编程--调用opencv
最近的我们已经将整个项目搭起来了,项目比较复杂.由于我们做的是检索系统,所以我们用asp.net(c#)做了网页,但是算法的实现是在matlab下,所以我们不得不用matlab生成动态链接库dll,然 ...
- matlab封装DLL混合编程总结
最近做了个项目要用到matlab做些算法处理,然后用.net项目调用这个类,我把这个matlab封装dll总结了下如下: matlab是商业数学软件,优势是在算法开发上面有很强的功能,提供了很多数学算 ...
随机推荐
- Ansible自动化运维工具及其常用模块
Ansible自动化运维工具及其常用模块 目录 Ansible自动化运维工具及其常用模块 一.Ansible简介 1. Ansible概述 2. Ansible作用 3. Ansible的工作模块 4 ...
- Java == 和 equals 的区别(面试描述)
== == 是一个比较运算符 既可以判断基本类型,又可以判断引用类型 如果判断基本数据类型,判断的是值是否相等 如果判断的是引用类型,判断的是地址是否相等,判断是不是同一个对象 equals equa ...
- c++ Message与Folder 拷贝 析构(没有动态空间的类)
c++ Message与Folder 拷贝 析构(没有动态空间的类) 1.两个类里边分别保存一个对方的set表,当前类有拷贝或者销毁时需要更新另一个类的set表. 2.两个类都需要访问对方的priva ...
- Spring Boot AOP 扫盲,实现接口访问的统一日志记录
AOP 是 Spring 体系中非常重要的两个概念之一(另外一个是 IoC),今天这篇文章就来带大家通过实战的方式,在编程猫 SpringBoot 项目中使用 AOP 技术为 controller 层 ...
- 已经安装的nginx增加额外配置步骤
这里以安装第三方ngx_http_google_filter_module模块为例nginx的模块是需要重新编译nginx,而不是像apache一样配置文件引用.so1. 下载第三方扩展模块ngx_h ...
- CobaltStrike逆向学习系列(6):Beacon sleep_mask 分析
这是[信安成长计划]的第 6 篇文章 关注微信公众号[信安成长计划] 0x00 目录 0x01 C2Profile 分析 0x02 set userwx "true" 0x03 s ...
- bugku-Web md5 collision writeup
访问题目链接,得到提示input a,而题目是md5 collision,md5碰撞.所以找一个md5是oe开头的值,get方式传参过去,PAYLOAD http://114.67.246.176:1 ...
- Meterpreter后渗透阶段关闭防火墙与杀毒软件
- C#foreach 本质( 鸭子类型遍历)
探讨关于C#中Foreach的本质 要实现foreach需要满足什么条件? 只要类中实现类中的GetEnumerator()方法.MoveNext()方法.Current属性(俗称鸭子类型)都可以使用 ...
- 平平无奇的项目「GitHub 热点速览 v.22.10」
不知道大家对高星项目什么印象?提到这个词第一个想到哪个项目呢?本周有几个项目看着普普通通,却完成了一周 2k+ star 的事迹.比如 SingleFile,它是个浏览器扩展,点击图标之后即可保存一个 ...