这样的fortran程序动态库该如何调用?

Inyoureyes 2006-04-26 05:47:27
在fortran程序中,有一个函数定义形式如下:
subroutine SUB(In,Out),两个参数声明为:

real, dimension(10) :: In
real, dimension(9) :: Out
该函数将根据数组In进行一系列计算,并将计算结果保存在数组Out中,文件已编译为动态库,并引出了该函数:
!DEC$ ATTRIBUTES C,ALIAS:'SUB'::SUB
!DEC$ ATTRIBUTES DLLEXPORT::SUB
!DEC$ ATTRIBUTES REFERENCE::In
!DEC$ ATTRIBUTES REFERENCE::Out
请问在C++中如何将调用这样的动态库,谢谢大家了!解决问题就结分,绝不拖延!
...全文
1160 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
ccccffff 2006-04-27
  • 打赏
  • 举报
回复
up
jixingzhong 2006-04-26
  • 打赏
  • 举报
回复
楼主看看 GCC技术大全中的相关的混合编程部分的内容吧 ~
逸学堂 2006-04-26
  • 打赏
  • 举报
回复
1.VC++与Fortran的混合编程
目前VC和VF都是基于WINDOWS的IDE开发环境,并且在安装同一版本的Fortran时会自动集成到VS的开发环境,这样就给我们在进行调用Fortran时提供了三种不同的方法。
1.1 同一工程下包含不同语言的文件
集成后的编译器可以根据不同的扩展名选择编译方式,生成目标代码文件.OBJ,然后按照指定的调用方式进行链接,生成可执行文件.EXE。
在2 中我们提到调用规则,在C语言中调用Fortran的函数或模块,必须在函数名前面冠以_stdcall关键字作为调用方式①,这样编译器会给我们处理包括参数传递顺序、参数传递方式、堆栈处理和命名修饰等问题。而在C++语言中,尽管在开发C++语言时考虑兼容C方式,即C++对函数的调用规则与C是一致的,但是C++在命名转换上与C语言是不一致的。参考以下对外部函数的声明:
1 C语言调用Fortran模块的声明:
extern void _stdcall SUBROUTINE(argType arg1,……);
extern float _stdcall FUNCTION(argType arg1,……);
2 C++语言调用Fortran模块的声明:
extern “C” { void _stdcall SUBROUTINE(argType arg1,……); }
extern “C” { float _stdcall FUNCTION(argType arg1,……); }
外部函数声明仅仅给调用过程提供函数的入口地置,目的是为了保证编译通过。
在链接生成可执行文件时,主调用过程根据函数名链接被调用模块,找到模块则可链接成功,有了调用规则和命名规则的修饰字进行转换,才能保证运行正常。
1.2 调用Fortran语言生成的dll模块:
如果为了调用在Fortran中已有的模块或者为了提高处理速度,可以考虑将已有程序或者算法用Fortran语言做成dll的模块,便于移植和修改,这样即使原dll模块中的算法做过修改,只要保证函数或子例行程序名字和入口参数不变,主调用过程无须进行重新修改或者编译。Dll文件的好处很多,感兴趣的读者可以参考相关计算机书籍。
Fortran程序制作dll模块的过程如下:
首先利用向导制作一个空的Visual Fortran dll项目,在生成的文件中可以看到用cDEC $ ATTRIBUTES DLLEXPORT 指令声明的函数,这个函数即为该dll输出的子程序,用户可以在外部程序中调用它来完成一定的功能。可以在一个dll文件中添加cDEC $ ATTRIBUTES DLLEXPORT指令声明多个函数、过程或要输出的数据。例如,
!在dll中声明输出函数 Fact
INTEGER*4 FUNCTION FACT(N)
!DEC$ ATTRIBUTES DLLEXPORT::FACT
INTEGER*4 N
……
END FUNCTION FACT
!在dll中声明子例行程序 ARRAYTEST
SUBROUTINE ARRAYTEST(ARR)
!DEC$ ATTRIBUTES DLLEXPORT::ARRAYTEST
REAL*4 ARR(3,7)
……
END SUBROUTINE ARRAYTEST
1.3 VC中调用IMSL数学库函数
这是混合编程比较实用的部分,笔者在使用过程中发现运用上面的改变调用规则和命名转换方法仍然无法在VC中直接调用VF的数学库,编译报错为: unresolved external call,即无法决议的外部调用。即使使用VC的编译指令#pragma comment (lib, “***.lib”)加入调用IMSL所需的三个lib文件,仍然存在未解决的外部调用错误,原因是内部调用过程不可知。
研究Compaq Visual Fortran的在线帮助可以发现,在Fortran程序中,要使用IMSL库,也需加入编译指令USE NUMERICAL_LIBRARIES来包含确切的头文件和库,这样就可以直接使用IMSL数学库中的函数。基于以上分析,我们可以定制dll,将要用到的数学函数包括到自己的模块中,然后在VC中使用,参考下面的例子:
REAL*4 FUNCTION FCBRT(A)
!Expose Function FCBRT to users of this DLL
!DEC$ ATTRIBUTES DLLEXPORT::FCBRT
USE numerical_libraries
REAL*4 A[VALUE]
!Variables
!Body of the Function
FCBRT=CBRT(A)
END FUNCTION FCBRT
注意输出函数名不要和IMSL库中的函数同名,否则生成dll时将报与库函数命名冲突!
当然用户在实际使用过程中为了简单的调用若干个数学函数,还要进行库函数的定制与打包,这是不大实际的。
以下提供一种简单的方法在VC中调用IMSL库函数,参考表一:

Static or DLL 多线程? 是否使用C调试库 使用的Fortran链接库存 使用的C链接库存
Static 否 否 dfor.lib libc.lib
Static 否 是 dfor.lib libcd.lib
Static 是 否 dformt.lib libcmt.lib
Static 是 是 dformt.lib libcmtd.lib
DLL 否 否 dfordll.lib(dforrt.dll) msvcrt.lib(msvcrt.dll)
DLL 否 是 dfordll.lib(dforrt.dll) msvcrtd.lib(msvcrtd.dll)
DLL 是 否 dformd.lib(dformd.dll) msvcrt.lib(mvcrt.dll)
DLL 是 是 dformd.lib(dformd.dll) msvcrtd.lib(msvcrtd.dll)
表一

在编程实践中,根据表一的调用依赖关系,笔者总结出了在VC工程中直接调用IMSL数学库的方法。第一,在控制台(console)应用程序中调用 IMSL库函数,必须包含dfor.lib,dfconsol.lib,在MFC应用程序中调用IMSL库函数,则必须包含dformd.lib,当然上述两种情况的工程要想调用Fortran提供的数学库,如下三个库文件是基本的:
1 Imsl.lib IMSL静态库,包含了Fortran77 和 Fortran90 所有函数和子例行程序;
2 Imsls_err.lib IMSL错误处理库;
3 Imslmpistub.lib 基于多CPU的并行处理库(对于单CPU的PC机用户可省)
读者可以根据表一,结合在项目中Project菜单的Setting项中有关编译器参数对相应的库文件进行修改。
2 提供简单算例
在计算机图形学中关于曲线、曲面进行插值或拟合,将大量使用求解线性方程组。如在求B样条曲线插值问题中,要先进行反求控制顶点,然后根据B样条基求出进行插值,我们利用VC来完成界面,利用IMSL提供的数学函数完成计算。
例题:已知型值点序列Pi,i=0,1,2…,7:

P[0] P[1] P[2] P[3] P[4] P[5] P[6] P[7]
Abscissae x 8.125 8.400 9.000 9.485 9.600 9.959 10.166 10.200
Ordinates y 0.0774 0.099 0.28 0.6 0.708 1.20 1.80 2.177

求控制顶点序列。
反求B杨条曲线控制顶点的数学问题是:
D表示de Boor控制顶点,P已知型值点列和边界条件向量。

在VC中调用IMSL解线性方程组的函数LSASF/DLSASF求解,完整代码如下:

#include <iostream>
using namespace std;

#include <math.h>

#pragma comment (lib, "dfor")
#pragma comment (lib, "dfconsol")
#pragma comment (lib, "imsl
寻开心 2006-04-26
  • 打赏
  • 举报
回复
http://www.zahui.com/html/1/1841.htm
YFY 2006-04-26
  • 打赏
  • 举报
回复
这个也太冷门了,阿没有研究,只能友情UP了。
healer_kx 2006-04-26
  • 打赏
  • 举报
回复
我是来UP的。

64,266

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧