声振论坛

 找回密码
 我要加入

QQ登录

只需一步,快速开始

查看: 2194|回复: 0

[其他相关] 基于动态链接库DLL实现FOTRAN与VC++混合编程

[复制链接]
发表于 2015-10-27 07:56 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?我要加入

x
编译环境:
Windows 7、Visual Studio 2008 Professional 、Intel Visual Fotran Compiler Professional V11.1.060

方法一:把FORTRAN子程序做成动态链接库供VC++主程序显式调用。

在此方法中,应用程序在运行时通过函数调用来显示装载和卸载DLL,并通过函数指针来调用DLL的导出函数。使用显示链接的基本方式:调用LoadLibrary或AfexLoadLibrary装载DLL并得到模块句柄;调用GetProcAddress来获得导出函数的指针;在使用完毕时,调用FreeLibrary或AfxFreeLibrary函数释放DLL。

(1)创建FORTRAN DLL工程(工程名:Fsubroutines;添加源文件:Fsubroutines.f90),生成 Fsubroutines.dll 文件供调用。
  1. !  Fsubroutines.f90
  2. !  FUNCTIONS/SUBROUTINES exported from  Fsubroutines.dll
  3. !  Fsubroutines      - subroutine
  4. !
  5. INTEGER*4 FUNCTION Fact (n)
  6.    !DEC$ ATTRIBUTES DLLEXPORT,STDCALL,ALIAS:'_FACT@4'::Fact
  7.       INTEGER*4 n [VALUE]
  8.       INTEGER*4 i, amt
  9.       amt = 1
  10.       DO i = 1, n
  11.         amt = amt * i
  12.       END DO
  13.       Fact = amt
  14.    write(*,*)"Mixed calls succeed!"
  15. END FUNCTION Fact

  16. SUBROUTINE Pythagoras (a, b, c)
  17.    !DEC$ ATTRIBUTES DLLEXPORT,STDCALL,ALIAS:'_PYTHAGORAS@12'::Pythagoras
  18.       REAL*4 a [VALUE]
  19.       REAL*4 b [VALUE]
  20.       REAL*4 c [REFERENCE]
  21.       c = SQRT (a * a + b * b)
  22. END SUBROUTINE Pythagoras
复制代码


(2)创建win32 console application(工程名:CFotran;添加源文件:CFortran.cpp),调用 Fsubroutines.dll。

//CFortran.cpp
//C++显式调用FORTRAN动态链接库
  1. #include <stdio.h>
  2. #include <iostream>
  3. #include <windows.h>

  4. using namespace std;

  5. //extern "C" {int _stdcall FACT (int n);}
  6. //extern "C" {void _stdcall  PYTHAGORAS (float a, float b, float *c);}

  7. int main()
  8. {
  9. //声明调用约定
  10. typedef int (_stdcall * FACT)(int n);
  11. typedef void (_stdcall * PYTHAGORAS)(float a, float b, float *c);
  12. //此处紫色部分应与FORTRAN源文件中紫色部分一致
  13. //加载动态库文件
  14. HINSTANCE hLibrary=LoadLibrary("D:\\dll\\Fsubroutines.dll");
  15. //由于FORTRAN编译后生成的.dll文件路径太深,故将生成的 Fsubroutines.dll 复制到 D:\dll 目录中
  16. if(hLibrary==NULL)
  17. {
  18.   cout<<"can't find the dll file (Fsubroutines.dll)"<<endl;
  19.   return -1;
  20. }


  21. //获得Fortran导出函数FACT的地址
  22. FACT fact=(FACT)GetProcAddress(hLibrary,"_FACT@4");
  23. //注意此处红色部分应与FORTRAN源文件红色部分相同
  24. if(fact==NULL)
  25. {
  26.   cout<<"can't find the function file (FACT)."<<endl;
  27.   return -2;
  28. }

  29. //获得Fortran导出函数PYTHAGORAS的地址
  30. PYTHAGORAS pythagoras=(PYTHAGORAS)GetProcAddress(hLibrary,"_PYTHAGORAS@12");
  31. //注意此处蓝色部分应与FORTRAN源文件蓝色部分相同
  32. if(pythagoras==NULL)
  33. {
  34.   cout<<"can't find the function file (PYTHAGORAS)."<<endl;
  35.   return -2;
  36. }
  37.     float c;
  38.     printf("Factorial of 7 is: %d\n", fact(7));
  39.     pythagoras (30, 40, &c);
  40.     printf("Hypotenuse if sides 30, 40 is: %f\n", c);
  41. FreeLibrary(hLibrary); //卸载动态库文件
  42. getchar();
  43. return 0;

  44. }
复制代码



方法二:把FORTRAN子程序做成库文件供VC++主程序隐式调用。

在此方法中,使用DLL的应用程序链接到编译DLL是通过生成的导入库lib文件,在执行这个程序时,系统也需要装载其他所需要的DLL。在程序退出之前,DLL一直存在于该程序进程的地址空间,占据内存。

(1) 创建FORTRAN DLL工程(工程名:Fsubroutines;添加源文件:Fsubroutines.f90),生成 Fsubroutines.dll  和 Fsubroutines.lib文件供调用。
  1. !  Fsubroutines.f90
  2. !
  3. !  FUNCTIONS/SUBROUTINES exported from Fsubroutines.lib:
  4. !  Fsubroutines      - subroutine
  5. !
  6. INTEGER*4 FUNCTION Fact (n)
  7. !ms$if .not. defined(LINKDIRECT)
  8. !ms$attributes dllexport,stdcall,alias:'_Fact@4'::Fact
  9. !ms$endif  
  10.       INTEGER*4 n [VALUE]
  11.       INTEGER*4 i, amt
  12.       amt = 1
  13.       DO i = 1, n
  14.         amt = amt * i
  15.       END DO
  16.       Fact = amt
  17.    write(*,*)"Mixed calls succeed!"
  18. END FUNCTION Fact

  19. SUBROUTINE Pythagoras (a, b, c)
  20. !ms$if .not. defined(LINKDIRECT)
  21. !ms$attributes dllexport,stdcall,alias:'_Pythagoras@12'::Pythagoras
  22. !ms$endif      
  23.    REAL*4 a [VALUE]
  24.       REAL*4 b [VALUE]
  25.       REAL*4 c [REFERENCE]
  26.       c = SQRT (a * a + b * b)
  27. END SUBROUTINE Pythagoras
复制代码


(2)创建win32 console application(工程名:CFotran;添加源文件:CFortran.cpp),添加 Fsubroutines.lib到工程,动态调用 Fsubroutines.dll。
注:将上一步生成的 Fsubroutines.dll  和 Fsubroutines.lib 复制到 CFortran.cpp所在的目录
  1. //CFortran.cpp
  2. #include <stdio.h>
  3. #include <iostream>

  4. extern "C" {int _stdcall Fact (int n);}
  5. extern "C" {void _stdcall  Pythagoras (float a, float b, float *c);}

  6. int main()
  7. {
  8.     float c;
  9.     printf("Factorial of 7 is: %d\n", Fact(7));
  10.     Pythagoras  (30, 40, &c);
  11.     printf("Hypotenuse if sides 30, 40 is: %f\n", c);
  12. }
复制代码
回复
分享到:

使用道具 举报

您需要登录后才可以回帖 登录 | 我要加入

本版积分规则

QQ|小黑屋|Archiver|手机版|联系我们|声振论坛

GMT+8, 2024-12-23 05:34 , Processed in 0.071060 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表