一、C++动态调用Fortran DLL
(1)创建FORTRAN DLL工程,生成forsubs.dll文件供调用。
! forsubs.f90 ! ! FUNCTIONS/SUBROUTINES exported from FORSUBS.dll: ! FORSUBS - subroutine ! INTEGER*4 FUNCTION Fact (n) !DEC$ ATTRIBUTES DLLEXPORT::Fact INTEGER*4 n [VALUE] INTEGER*4 i, amt amt = 1 DO i = 1, n amt = amt * i END DO Fact = amt write(*,*)"Mixed calls succeed!" END SUBROUTINE Pythagoras (a, b, c) !DEC$ ATTRIBUTES DLLEXPORT::Pythagoras REAL*4 a [VALUE] REAL*4 b [VALUE] REAL*4 c [REFERENCE] c = SQRT (a * a + b * b) END
注意:!DEC$ ATTRIBUTES DLLEXPORT::Fact这一句很重要,如果没有这一句的话,C++程序找不到这个接口。
(2)创建win32 console application,调用forsubs.dll。
/* File CMAIN.C */ //C++显式调用FORTRAN动态链接库 #include <stdio.h> #include <iostream.h> #include <windows.h> main() { //声明调用约定 typedef int (_stdcall * FACT)(int n); typedef void (_stdcall * PYTHAGORAS)(float a, float b, float *c); //加载动态库文件 HINSTANCE hLibrary=LoadLibrary("forsubs.dll"); if(hLibrary==NULL) { cout<<"can't find the dll file"<<endl; return -1; } //获得Fortran导出函数FACT的地址 FACT fact=(FACT)GetProcAddress(hLibrary,"FACT"); if(fact==NULL) { cout<<"can't find the function file."<<endl; return -2; } //获得Fortran导出函数PYTHAGORAS的地址 PYTHAGORAS pythagoras=(PYTHAGORAS)GetProcAddress(hLibrary,"PYTHAGORAS"); if(pythagoras==NULL) { cout<<"can't find the function file."<<endl; return -2; } float c; printf("Factorial of 7 is: %d ", fact(7)); pythagoras (30, 40, &c); printf("Hypotenuse if sides 30, 40 is: %f ", c); FreeLibrary(hLibrary); //卸载动态库文件 return 0; }
二、调试Fortran DLL
设置Fortran程序的项目属性,Debugging->Command中,设置为测试程序的EXE文件路径。
设置Command之后,直接调试Fortran DLL 项目即可
上文的c++部分编译的话提示找不到iostream.h
改为
#include<iostream>
using namespace std;
就可以编译通过了
debug的时候遇到问题
原因是调用方式出了问题,应该把
typedef int (_stdcall * FACT)(int n); 改为
typedef int (_cdecl * FACT)(int n);
这样的话debug就不会出现上述错误了。
还有一个问题:我用fortran编的程序里边用了imsl库,如果什么库都没用的话直接把生成的dll拷到debug目录下就可以了,但是我加了库,debug的时候就提示我缺少 mkl_intel_thread.dll,mkl_core.dll和mkl_avx2.dll这三个动态库。查找了一下在
C:Program Files (x86)IntelComposer XE 2013 SP1 edistia32mkl里边,为以防万一,可以把mkl里边的dll全拷进来。
加进去就ok了。