文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>VC 中调用Fortran动态链接库函数开发说明

VC 中调用Fortran动态链接库函数开发说明

时间:2010-08-18  来源:破碎

 VC 中调用Fortran动态链接库函数开发说明

 

说明:使用Fortran建立动态链接库,在C/C++语言环境中载入动态链接库,并调用动态链接库中函数。此方法使用动态载入动态链接库的方法。

 

开发环境:

       Compaq Visual Fortran 6.5

       Visual C++ 6.0

 

1. 程序中特殊要求:

1.1  Fortran :

在Fortran函数内部添加以下声明:

!DEC$  ATTRIBUTES  DLLEXPORT::FunctionName

表示这个函数为DLL导出函数,其中FunctionName为函数名

 

特别提示:Fortran 函数调用传递的参数为传地址。所以在C/C++语言中调用的时候要传递参数的地址。

 

1.2 C/C++:

1.2.1 加载动态链接库:

HMODULE LoadLibrary(PCTSTR pszDLLPathName);

 

HMODULE LoadLibraryEx(

PCTSTR pszDLLPathName,               //DLL路径以及名称

HANDLE hFile,

DWORD dwFlags);                            //加载选项

这两个函数会在将一个DLL映射到进程的地址空间中。返回值类型为HMODULE(和HINSTANCE等价)为DLL被映射的虚拟内存地址。

使用这两个函数将DLL动态加载。

LoadLibraryEx函数中 参数hFile为系统为将来扩充所保留,现在必须设为NULL.

dwFlags 为动态链接库加载方式选项, 一般使用DONT_RESOLVE_DLL_REFFERENCE, 告诉系统只需将DLL映射到进程地址空间。

 

1.2.2 卸载动态链接库:

BOOL FreeLibrary(HMODULE hInstDll);

 

1.2.3 检索指定的动态链接库(DLL)中的输出库函数地址:

FARPROC GetProcAddress(

  HMODULE hModule, // DLL模块句柄

  LPCSTR lpProcName );// 函数名

 

返回值为函数的指针,记得要强制类型转换,否则编译过程中会发生错误。同时,Fortran语言中时忽略大小写的,所以检索的时候要求函数名全部为大写字母。

2. 实例

2.1 实例1:

说明:Fortran实现两个整数加法

 

Fortran部分:

       新建项目,项目类型为Fortran Dynamic Link Library, 项目名称为testA,选择An empty DLL application, 添加一个test.f90文件,文件中编辑如下内容:

function GetAdd(a, b) result(r)

 

       implicit none

 

       !DEC$ ATTRIBUTES DLLEXPORT::GetAdd

       integer :: a

       integer :: b

       integer :: r

 

       r = a + b

       return

end

 

 

编译生成DLL文件。

 

C/C++ 部分:

       新建一个MFC AppWizard(exe)项目,项目名称为 testAMFC, 选择Dialog based选项。

编辑资源:

 

删除ok cancel 按钮,添加一个按钮,按钮标题ADD, ID为IDC_BUTTON_ADD。设为缺省按钮(就是敲回车等于按了这个按钮)。

添加三个可编辑文本框,ID分别为IDC_EDIT_A, IDC_EDIT_B, IDC_EDIT_RESULT

为三个文本框添加成员变量 变量类型为 int 变量名分别为 m_a, m_b, m_result。

为按钮ADD添加控制函数,函数名称为OnButtonAdd

编写此函数:

void CTestAMFCDlg::OnButtonAdd()

{

       this->UpdateData();

       HMODULE hDll = LoadLibraryEx(TEXT("testA.dll"), NULL,

                     DONT_RESOLVE_DLL_REFERENCES);

 

       if (!hDll)

       {

              MessageBox("加载动态链接库失败", "ERROR", MB_OK);

              return;

       }

 

       int (__stdcall *proc)(int *, int *);       //注意声明方式指向函数的指针,要求有__stdcall

 

       proc = (int (__stdcall *)(int *, int *))GetProcAddress(hDll, "GETADD");

 

       if (!proc)

       {

              MessageBox("加载函数失败", "ERROR", MB_OK);

              FreeLibrary(hDll);

              return;

       }

 

       m_result = proc(&m_a, &m_b);

       this->UpdateData(false);

FreeLibrary(hDll);

}

 

将Fortran编译出来的DLL文件拷贝到当前项目目录,编译执行。

 

2.2 实例二:

说明:调用Fortran动态链接库实现可变长数组加法。

Fortran部分:

       新建项目,项目类型为Fortran Dynamic Link Library, 项目名称为test,选择An empty DLL application, 添加一个test.f90文件,文件中编辑如下内容:

function GetAdd(a, b, n, r)  result(rr)

 

       implicit none

 

       !DEC$ ATTRIBUTES DLLEXPORT::GetAdd

 

       integer :: a(*)         !参数为一个可变大小的一维数组

       integer :: b(*)         !参数为一个可变大小的一维数组

       integer :: r(*)          !参数为一个可变大小的一维数组

       integer :: n

       integer :: i

       integer :: rr

 

       do i=1, n               !使用循环计算加法

              r(i) = a(i) + b(i)

       end do

 

       rr = n

       return

end

 

 

C/C++ 部分:

       新建一个MFC AppWizard(exe)项目,项目名称为 testAMFC, 选择Dialog based选项。

编辑资源:

 

删除ok cancel 按钮,添加一个按钮,按钮标题ADD, ID为IDC_BUTTON_ADD。设为缺省按钮(就是敲回车等于按了这个按钮)。

添加九个可编辑文本框,ID分别为IDC_EDIT_A1 ~ IDC_EDIT_A3, IDC_EDIT_B1 ~ IDC_EDIT_B3, IDC_EDIT_C1 ~ IDC_EDIT_C3。

分别为其添加成员变量      

m_a1,m_a2,m_a3; m_b1,m_b2,m_b3; m_c1,m_c2,m_c3;

 

为按钮ADD添加控制函数 函数名称为OnButtonAdd

编辑此函数

void CTestmfcDlg::OnButtonAdd()

{

       this->UpdateData();

       int a[3];

       int b[3];

       int c[3];

       int n = 3;

 

/*

       m_a1 = 1;

       m_a2 = 2;

       m_a3 = 3;

 

       m_b1 = 3;

       m_b2 = 2;

       m_b3 = 1;

*/

//     this->UpdateData(false);

 

       a[0] = m_a1;

       a[1] = m_a2;

       a[2] = m_a3;

 

       b[0] = m_b1;

       b[1] = m_b2;

       b[2] = m_b3;

 

       HMODULE hDll = LoadLibraryEx(TEXT("test.dll"), NULL,

                     DONT_RESOLVE_DLL_REFERENCES);

 

       if (!hDll)

       {

              MessageBox("加载动态链接库失败", "ERROR", MB_OK);

FreeLibrary(hDll);

              return;

       }

 

     //注意声明方式指向函数的指针,要求有__stdcall

       int (__stdcall *proc)(int *, int *, int *, int *);

 

       proc = (int (__stdcall *)(int *, int *, int *, int *))GetProcAddress(hDll, "GETADD");

 

       if (!proc)

       {

              MessageBox("加载函数失败", "ERROR", MB_OK);

              FreeLibrary(hDll);

              return;

       }

 

       proc(a, b, &n, c);

 

       m_c1 = c[0];

       m_c2 = c[1];

       m_c3 = c[2];

 

       this->UpdateData(false);

       FreeLibrary(hDll);

}

 

将Fortran编译出来的DLL文件拷贝到当前项目目录,编译执行。

还有一个问题之前没有提到,就是Fortran的函数参数传递为传址的方式,所以调用fortran动态链接库里面的函数的时候传递的都是地址。

相关阅读 更多 +
排行榜 更多 +
开心动动脑安卓版 v1.0 手机版

开心动动脑安卓版 v1.0 手机版

休闲益智 下载
不良人破局手游下载

不良人破局手游下载

角色扮演 下载
云海之下手游下载

云海之下手游下载

角色扮演 下载