【混合编程】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是商业数学软件,优势是在算法开发上面有很强的功能,提供了很多数学算 ...
随机推荐
- 基于Hexo的博客管理恢复
若重装电脑或更换电脑后 该如何恢复博客的管理? 1.确保之前博客源代码文件夹及文件保存在公库或私库中 例如: 我这里采用的是闭源存放方案,故为私库 这是源码文件样式 2.在新电脑上重新安装git,no ...
- Pandas中Series与Dataframe的区别
1. Series Series通俗来讲就是一维数组,索引(index)为每个元素的下标,值(value)为下标对应的值 例如: arr = ['Tom', 'Nancy', 'Jack', 'Ton ...
- Oracle用户创建、删除和授权等方法总结
一.查看用户及权限 1.查询所有用户: 1.1.查看所有用户基本信息 select * from all_users; 1.2.查看所有用户相信信息 select * from dba_users; ...
- 大地坐标BLH转平面坐标xyh(高斯投影坐标正算) Java版
技术背景 做过位置数据处理的小伙伴基本上都会遇到坐标转换,而基于高斯投影原理的大地坐标转平面坐标就是其中一种坐标转换,坐标转换的目的就是方便后面数据的处理工作,大地坐标转高斯平面坐标常用的有两种,即3 ...
- 初识面向对象(Day17-Day18)
人狗大战的游戏 你现在是一家游戏公司的开发人员,现在需要你开发一款叫做<人狗大战>的游戏,你就思考呀,人狗作战,那至少需要2个角色,一个是人, 一个是狗,且人和狗都有不同的技能,比如人拿棍 ...
- 《操作系统导论》第14章 | 内存操作API
内存类型 在运行一个C程序的时候,会分配两种类型的内存.第一种称为栈内存,它的申请和释放操作是编译器来隐式管理的,所以有时也称为自动内存.假设需要在func()函数中为一个整形变量x申请空间,我们只需 ...
- Netty源码解析一——线程池模型之线程池NioEventLoopGroup
本文基础是需要有Netty的使用经验,如果没有编码经验,可以参考官网给的例子:https://netty.io/wiki/user-guide-for-4.x.html.另外本文也是针对的是Netty ...
- Java的泛型机制
Java的泛型机制 泛型是 Java 从 JDK5 开始引入的新特性,本质上是参数化类型,即所操作的数据类型被指定为一个参数.这意味着编写的代码可以被很多不同类型的对象所重用. 1. 泛型的使用方式 ...
- 多表查询思路、navicat可视化软件、python操作MySQL、SQL注入问题以及其他补充知识
昨日内容回顾 外键字段 # 就是用来建立表与表之间的关系的字段 表关系判断 # 一对一 # 一对多 # 多对多 """通过换位思考判断""" ...
- PostgreSQL VACUUM 之深入浅出 (三)
VACUUM 相关参数 对 VACUUM 有了一定的了解之后,下面系统介绍下 VACUUM 相关参数. VACUUM 相关参数主要分为三大类. 第一类 与资源相关参数 #--------------- ...