【混合编程】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的更多相关文章

  1. [转载:]C#与Fortran混合编程之本地调用Fortran动态链接库

    前言 C#发展到现在,已是一门相当完善的语言,他基于C语言风格,演化于C++.并依靠强大的.NET底层框架.C#可以用来快速构建桌面及Web应用.然而在我们的实际工作中,尽管C#已经非常完善,但还是不 ...

  2. Matlab与C++混合编程 1--在C++中调用自己写的matlab函数

    在Visual Studio中使用C++中调用MATLAB程序 在matlab中可以通过mbuild工具将.m文件编译成dll文件供外部的C++程序调用,这样就可以实现matlab和C++混合编程的目 ...

  3. 【调试经验】C++和C的混合编程以及库调用

    问题背景 这两天在移植一个开源的库,偏底层的那种,所以对架构有一些依赖.源码的编译是通过Makefile来构建,怎奈公司的架构用的是CMAKE,所以就在开源的顶层和子目录分别构建了CMakeList, ...

  4. python c++ 混合编程中python调用c++string返回类型的函数,python中返回为数字的解决办法

    本随笔解决 Python使用ctypes 调用c++dll 字符串返回类型函数,在python中显示为数字:原文解决方案见so: https://stackoverflow.com/questions ...

  5. C#调用Fortran生成的DLL的方法报内存不足

    最近在研究一个程序,公司给的,程序是VB写的,程序里面还有一个计算的模型,用Fortran语言写的. 在调试到这个模型里面的方法时报错,说是内存不足,于是就在网上查找方法,看了两篇博客之后问题解决了. ...

  6. Fortran与C混合编程(转自Ubuntu)

    Fortran与C混合编程 由于 GNU 的 Fortran 和 C 语言二者的函数彼此可以直接相互调用,所以混合编程可以非常容易地实现.只要你足够仔细,确保函数调用时传递的参数类型正确,函数就可以在 ...

  7. 【原创】Matlab.NET混合编程技巧之直接调用Matlab内置函数

                  本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新    Matlab和C#混合编程文章目录 :[目录]Matlab和C#混合编程文章目录 在我的上一篇文章[ ...

  8. matlab和C/C++混合编程--调用opencv

    最近的我们已经将整个项目搭起来了,项目比较复杂.由于我们做的是检索系统,所以我们用asp.net(c#)做了网页,但是算法的实现是在matlab下,所以我们不得不用matlab生成动态链接库dll,然 ...

  9. matlab封装DLL混合编程总结

    最近做了个项目要用到matlab做些算法处理,然后用.net项目调用这个类,我把这个matlab封装dll总结了下如下: matlab是商业数学软件,优势是在算法开发上面有很强的功能,提供了很多数学算 ...

随机推荐

  1. Redis小秘密

    Redis小秘密 临渊羡鱼,不如退而织网. 一.Redis基本数据类型 想必很多人都能脱口而出String.List.Hash.Sorted Set和Set五种基本数据类型. 以及五大基本数据类型简要 ...

  2. 显式锁之ReentrantLock实现

    下图是Lock接口清单,定义了一些抽象的锁操作.Java本身提供了内部锁机制,那么还需要显示Lock,何用?与内部加锁机制不同,Lock提供了无条件.可轮询.定时.可中断的锁获取操作:所有加锁和解锁的 ...

  3. ssh 连接出现expecting SSH2_MSG_KEX_ECDH_REPLY失败解决

    问题描述: ssh连接通过ipsec后连接卡住:ssh -vvv显示: echo "1420" > /sys/class/net/eth0/mtu #把mtu值设置一下默认是 ...

  4. HBase学习记录-API

    delete.addColumns()和delete.addColumn()的区别 /** * delete.addColumns(); * delete.addColumn(); * 区别: * a ...

  5. Sqlmap数据库注入攻击

    实验目的 利用sqlmap命令破解出access数据中的admin的密码bfpns 实验原理 SQLMap是一个先进的自动化SQL注入工具,其主要功能是扫描.发现并利用给定的URL的SQL注入漏洞.目 ...

  6. [旧][Android] View 工作原理(一)

    备注 原发表于2016.05.23,资料已过时,仅作备份,谨慎参考 前言 本文参考<Android 开发艺术探索>及网上各种资料进行撰写,目的是为自己理清 Android 中 View 的 ...

  7. 【C#单元测试】 开篇

    官方:https://docs.microsoft.com/zh-cn/visualstudio/test/install-third-party-unit-test-frameworks?view= ...

  8. elasticsearch7.8.0,kibana7.8.0安装

    目录 Windows下安装Elasticsearch Linux下安装Elasticsearch docker下安装Elasticsearch Kibana安装 chrome ElasticSearc ...

  9. OJ教程--DevC++快捷键

    一些常用的快捷键如下: 1.F9编译 2.F10运行 3.F11编译+运行 4.Ctrl + Home键 跳转到当前文本的开头处. 5.Ctrl + End键 跳转到当前文本的末尾处. 6.Ctrl ...

  10. 【C#版本】微信公众号模板消息对接(二)(图文详解)

    本篇文章承接上一篇文章内容,点击此段文字传送至上一篇文章. 特此说明:本篇文章为个人原创文章,创作不易,未经作者本人同意.许可等条件,不得以任何形式搬运.转载.抄袭(等包括但不限于上述手段)本文章,否 ...