c++调用fortran程序中遇到的问题

一、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了。


原文地址:https://www.cnblogs.com/lianjiehere/p/5144440.html