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动态链接库里面的函数的时候传递的都是地址。

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

文章摘自:http://www.cnblogs.com/nervending/archive/2010/08/18/1802351.html

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值