【混合编程实例】C/C++调用FORTRAN编写的DLL
2013-02-20 15:22
435 查看
之前都是用C/C++写好一些公用函数并将其包装在DLL中以供某应用模块调用,这
方面的教程在网络上一搜一大堆,以后再抽空在这里用实例简单地讲述一下。这次
是用FORTRAN写好几个函数然后编译成DLL,然后在C语言程序中使用。
1、首先是编写一段代码,这里给出一个例子
! 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(*,*) "Call Fortran Sub...OK"
END ! Function Fact
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 ! SUBROUTINE Pythagoras
! EOF
以上!DEC$打头的两行,如第一个,其另一形式如下
!MS$IF .NOT. DEFINED(LINKDIRECT)
!MS$ATTRIBUTES DLLEXPORT::FACT
!MS$ENDIF
可分别替换之,而余下代码都是一样的。
2、如果你用的是诸如Intel Visual Fortran这样的IDE,那么
可以这样建立DLL框架([文件(File)]->[新建(New)]):
按一般习惯通常是先建立一个工程然后添加(新建)源文件并编辑代码,但我们也
可以先写好代码并保存到文件forsubs.f90然后将其添加到DLL工程forsubs中,
然后编译链接得到forsubs.dll
3、调用
调用方式至少有3种,我一般是用后两种:
(1)显式,即使用前先LoadLibrary使用后FreeLibrary,比较麻烦,用的少
(2)静态lib,建立静态工程并将上述函数导出到*.lib文件然后添加到需要应用它的工程中
(3)动态lib,这个是我的偏爱
以下分别提供(1)和(3)的示例。
方式(1)的一个实例如下
#ifndef _MBCS
#define _MBCS
#endif
#include <iostream>
#include <windows.h>
using namespace std;
typedef int (__stdcall *FACT)(int n);
typedef void (__stdcall *PYTHAGORAS)(float a,float b,float* c);
int main(void)
{
HINSTANCE hLibrary=LoadLibrary(TEXT("forsubs.dll"));
if(hLibrary==NULL)
{
cout<<"Cannot open forsubs.dll"<<endl;
system("pause");
return -1;
}
FACT fact=(FACT)GetProcAddress(hLibrary,"FACT");
PYTHAGORAS py=(PYTHAGORAS)GetProcAddress(hLibrary,"PYTHAGORAS");
if(fact==NULL||py==NULL)
{
cout<<"Cannot find function"<<endl;
system("pause");
return -2;
}
float c;
cout<<" Fact(7)="<<fact(7)<<endl;
py(30,40,&c);
cout<<" Hypotenuse of 30,40 is "<<c<<endl;
FreeLibrary(hLibrary);
system("pause");
return 0;
}
注意以突出颜色显示那几行。
方式(3)的一个实例如下
#ifndef _MBCS
#define _MBCS
#endif
#include <iostream>
using namespace std;
#pragma comment(lib,"forsubs.lib")
//C<-->CPP
extern "C" {int _stdcall FACT (int n);}
extern "C" {void _stdcall PYTHAGORAS (float a, float b, float *c);}
int main(void)
{
float c;
cout<<" Fact(7)="<<FACT(7)<<endl;
PYTHAGORAS(30,40,&c);
cout<<" Hypotenuse of 30,40 is "<<c<<endl;
system("pause");
return 0;
}
以上两例定义_MBCS宏是为设置“使用多字节字符集”。
运行结果截图如下
今后可能会继续完善,如果觉得有用请关注本博客的后续更新。
本文原创,FORTRAN代码由网络上源码改编,转载请注明出处fengyhack@netease
http://nwpu.fyh2008.blog.163.com/blog/static/99106304201312023411488/
方面的教程在网络上一搜一大堆,以后再抽空在这里用实例简单地讲述一下。这次
是用FORTRAN写好几个函数然后编译成DLL,然后在C语言程序中使用。
1、首先是编写一段代码,这里给出一个例子
! 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(*,*) "Call Fortran Sub...OK"
END ! Function Fact
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 ! SUBROUTINE Pythagoras
! EOF
以上!DEC$打头的两行,如第一个,其另一形式如下
!MS$IF .NOT. DEFINED(LINKDIRECT)
!MS$ATTRIBUTES DLLEXPORT::FACT
!MS$ENDIF
可分别替换之,而余下代码都是一样的。
2、如果你用的是诸如Intel Visual Fortran这样的IDE,那么
可以这样建立DLL框架([文件(File)]->[新建(New)]):
按一般习惯通常是先建立一个工程然后添加(新建)源文件并编辑代码,但我们也
可以先写好代码并保存到文件forsubs.f90然后将其添加到DLL工程forsubs中,
然后编译链接得到forsubs.dll
3、调用
调用方式至少有3种,我一般是用后两种:
(1)显式,即使用前先LoadLibrary使用后FreeLibrary,比较麻烦,用的少
(2)静态lib,建立静态工程并将上述函数导出到*.lib文件然后添加到需要应用它的工程中
(3)动态lib,这个是我的偏爱
以下分别提供(1)和(3)的示例。
方式(1)的一个实例如下
#ifndef _MBCS
#define _MBCS
#endif
#include <iostream>
#include <windows.h>
using namespace std;
typedef int (__stdcall *FACT)(int n);
typedef void (__stdcall *PYTHAGORAS)(float a,float b,float* c);
int main(void)
{
HINSTANCE hLibrary=LoadLibrary(TEXT("forsubs.dll"));
if(hLibrary==NULL)
{
cout<<"Cannot open forsubs.dll"<<endl;
system("pause");
return -1;
}
FACT fact=(FACT)GetProcAddress(hLibrary,"FACT");
PYTHAGORAS py=(PYTHAGORAS)GetProcAddress(hLibrary,"PYTHAGORAS");
if(fact==NULL||py==NULL)
{
cout<<"Cannot find function"<<endl;
system("pause");
return -2;
}
float c;
cout<<" Fact(7)="<<fact(7)<<endl;
py(30,40,&c);
cout<<" Hypotenuse of 30,40 is "<<c<<endl;
FreeLibrary(hLibrary);
system("pause");
return 0;
}
注意以突出颜色显示那几行。
方式(3)的一个实例如下
#ifndef _MBCS
#define _MBCS
#endif
#include <iostream>
using namespace std;
#pragma comment(lib,"forsubs.lib")
//C<-->CPP
extern "C" {int _stdcall FACT (int n);}
extern "C" {void _stdcall PYTHAGORAS (float a, float b, float *c);}
int main(void)
{
float c;
cout<<" Fact(7)="<<FACT(7)<<endl;
PYTHAGORAS(30,40,&c);
cout<<" Hypotenuse of 30,40 is "<<c<<endl;
system("pause");
return 0;
}
以上两例定义_MBCS宏是为设置“使用多字节字符集”。
运行结果截图如下
今后可能会继续完善,如果觉得有用请关注本博客的后续更新。
本文原创,FORTRAN代码由网络上源码改编,转载请注明出处fengyhack@netease
http://nwpu.fyh2008.blog.163.com/blog/static/99106304201312023411488/
相关文章推荐
- [编程实例]Dev-C++编写动态调用dll杀进程的程序
- Silverlight实用窍门系列:22.Silverlight使用WebService调用C++,Delphi编写的DLL文件【实例源码下载】
- Silverlight实用窍门系列:22.Silverlight使用WebService调用C++,Delphi编写的DLL文件【实例源码下载】
- VC与Matlab混合编程之调用动态链接库dll(C++)——<二>
- 混合编程--fortran调用C++采用ODBC形式连接MYSQL数据库
- 混合编程---c++调用matlab生成的dll----findCircles的应用
- C#调用C++编写的COM DLL
- c与matlab混合编程之dll调用
- 在VS2015中用C++编写可被其它语言调用的动态库DLL
- C#调用C++编写的COM DLL
- C++ 编写DLL文件给易语言调用
- asp.net mvc 调用C++编写的64位的dll引发System.BadImageFormatException
- 在VS2008环境下编写C语言DLL,并在C++和C#项目下调用
- Eclipse、MinGW、JNI编写C++生成dll, Java端调用的完整示例(附java.lang.UnsatisfiedLinkError解决方法)
- C#调用C++编写的COM DLL
- c调用c++编的dll,c++调用c编写的dll,extern “C”的用法
- 使用JNI进行混合编程:在Java中调用C/C++本地库
- Java学习之通过JNI调用C/C++编写的dll链接库(图文教程)
- c#.net下成功调用c++编写的标准dll
- c++与matla混合编程之一---调用matlab工具箱内的函数