马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?我要加入
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 文件供调用。
- ! Fsubroutines.f90
- ! FUNCTIONS/SUBROUTINES exported from Fsubroutines.dll
- ! Fsubroutines - subroutine
- !
- INTEGER*4 FUNCTION Fact (n)
- !DEC$ ATTRIBUTES DLLEXPORT,STDCALL,ALIAS:'_FACT@4'::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 FUNCTION Fact
- SUBROUTINE Pythagoras (a, b, c)
- !DEC$ ATTRIBUTES DLLEXPORT,STDCALL,ALIAS:'_PYTHAGORAS@12'::Pythagoras
- REAL*4 a [VALUE]
- REAL*4 b [VALUE]
- REAL*4 c [REFERENCE]
- c = SQRT (a * a + b * b)
- END SUBROUTINE Pythagoras
复制代码
(2)创建win32 console application(工程名:CFotran;添加源文件:CFortran.cpp),调用 Fsubroutines.dll。
//CFortran.cpp
//C++显式调用FORTRAN动态链接库
- #include <stdio.h>
- #include <iostream>
- #include <windows.h>
- using namespace std;
- //extern "C" {int _stdcall FACT (int n);}
- //extern "C" {void _stdcall PYTHAGORAS (float a, float b, float *c);}
- int main()
- {
- //声明调用约定
- typedef int (_stdcall * FACT)(int n);
- typedef void (_stdcall * PYTHAGORAS)(float a, float b, float *c);
- //此处紫色部分应与FORTRAN源文件中紫色部分一致
- //加载动态库文件
- HINSTANCE hLibrary=LoadLibrary("D:\\dll\\Fsubroutines.dll");
- //由于FORTRAN编译后生成的.dll文件路径太深,故将生成的 Fsubroutines.dll 复制到 D:\dll 目录中
- if(hLibrary==NULL)
- {
- cout<<"can't find the dll file (Fsubroutines.dll)"<<endl;
- return -1;
- }
- //获得Fortran导出函数FACT的地址
- FACT fact=(FACT)GetProcAddress(hLibrary,"_FACT@4");
- //注意此处红色部分应与FORTRAN源文件红色部分相同
- if(fact==NULL)
- {
- cout<<"can't find the function file (FACT)."<<endl;
- return -2;
- }
- //获得Fortran导出函数PYTHAGORAS的地址
- PYTHAGORAS pythagoras=(PYTHAGORAS)GetProcAddress(hLibrary,"_PYTHAGORAS@12");
- //注意此处蓝色部分应与FORTRAN源文件蓝色部分相同
- if(pythagoras==NULL)
- {
- cout<<"can't find the function file (PYTHAGORAS)."<<endl;
- return -2;
- }
- float c;
- printf("Factorial of 7 is: %d\n", fact(7));
- pythagoras (30, 40, &c);
- printf("Hypotenuse if sides 30, 40 is: %f\n", c);
- FreeLibrary(hLibrary); //卸载动态库文件
- getchar();
- return 0;
- }
复制代码
方法二:把FORTRAN子程序做成库文件供VC++主程序隐式调用。
在此方法中,使用DLL的应用程序链接到编译DLL是通过生成的导入库lib文件,在执行这个程序时,系统也需要装载其他所需要的DLL。在程序退出之前,DLL一直存在于该程序进程的地址空间,占据内存。
(1) 创建FORTRAN DLL工程(工程名:Fsubroutines;添加源文件:Fsubroutines.f90),生成 Fsubroutines.dll 和 Fsubroutines.lib文件供调用。
- ! Fsubroutines.f90
- !
- ! FUNCTIONS/SUBROUTINES exported from Fsubroutines.lib:
- ! Fsubroutines - subroutine
- !
- INTEGER*4 FUNCTION Fact (n)
- !ms$if .not. defined(LINKDIRECT)
- !ms$attributes dllexport,stdcall,alias:'_Fact@4'::Fact
- !ms$endif
- 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 FUNCTION Fact
- SUBROUTINE Pythagoras (a, b, c)
- !ms$if .not. defined(LINKDIRECT)
- !ms$attributes dllexport,stdcall,alias:'_Pythagoras@12'::Pythagoras
- !ms$endif
- REAL*4 a [VALUE]
- REAL*4 b [VALUE]
- REAL*4 c [REFERENCE]
- c = SQRT (a * a + b * b)
- END SUBROUTINE Pythagoras
复制代码
(2)创建win32 console application(工程名:CFotran;添加源文件:CFortran.cpp),添加 Fsubroutines.lib到工程,动态调用 Fsubroutines.dll。
注:将上一步生成的 Fsubroutines.dll 和 Fsubroutines.lib 复制到 CFortran.cpp所在的目录
- //CFortran.cpp
- #include <stdio.h>
- #include <iostream>
- extern "C" {int _stdcall Fact (int n);}
- extern "C" {void _stdcall Pythagoras (float a, float b, float *c);}
- int main()
- {
- float c;
- printf("Factorial of 7 is: %d\n", Fact(7));
- Pythagoras (30, 40, &c);
- printf("Hypotenuse if sides 30, 40 is: %f\n", c);
- }
复制代码 |