找回密码
 注册
Simdroid-非首页
查看: 469|回复: 17

[请教]Fortran程序里调用matlab函数

[复制链接]
发表于 2008-3-12 15:46:49 | 显示全部楼层 |阅读模式 来自 大连理工大学
有没有人有Fortran程序里调用matlab函数的例子,具体怎么操作啊,看一些相关的都看不明白
发表于 2008-3-20 11:21:36 | 显示全部楼层 来自 北京
Simdroid开发平台
很感兴趣,以前在做,现在没有时间,唉
MatlabX库包括数学运算、功能强大线性代数、
图形处理等功能和部分神经网络,用于扩展 MATLAB 的功能和运行速度,可以作为独立的工具使用,支持生成自己的独立运行程序,不要求客户电脑装有matlab。

在VB,VC,Dephi中使用该数学工具包可避免重复性劳动,从而减少开发人员实现算法和界面设计的困难,可大大提高开发效率,
http://matlabvbvc.blog.163.com/
回复 不支持

使用道具 举报

发表于 2008-3-21 21:35:43 | 显示全部楼层 来自 新加坡
不知道楼主还在关注这贴,下面给出一个在fortran中调用matlab编译生成的DLL的例子。

【试验环境】Windows 2003 server std,matlab r2007b,MinGW gcc 4.2 (sjlj)。Visual Studio 2005
【试验任务】实现在fortran程序中调用matlab编译生成的DLL。
【试验步骤】首先,创建一个简单的m代码,这里用拙作《深入浅出matlab7.x混合编程》中用到的mcctest01.m作为例子,它是一个很简单的m方程,程序代码如下:
  1. function mcctest01
  2. % MCCTEST01 Create some data and draw a 2D x-y plot
  3. %   mcctest01 is used to demonstrates how to convert M-functions into   
  4. %   library files and how to use created library files with MFC
  5. %   applications.
  6. %
  7. %   Inputs:
  8. %       None
  9. %   
  10. %   Output:
  11. %       None

  12. %
  13. %   Copyright (c) 2005 Dong Weiguo

  14. % create data
  15. x = 0:.01:20;
  16. y = x.*sin(x);

  17. % draw a plot
  18. plot(x,y);
  19. xlabel('x');
  20. ylabel('y');
复制代码
然后在matlab中编译mcctest01,生成libmcctest01.dll。注意,如果这是你第一次在matlab中使用mcc命令,你需要先运行mbuild -setup来配置。我使用Visual Studio 2005编译器。在matlab中执行如下命令:
  1. mcc -W cpplib:libmcctest01 -T link:lib mcctest01.m
复制代码
这里假设matlab中的当前工作环境是$MATLAB\work。结果将会产生若干文件,我们需要拷贝如下四个文件到我们的Fortran源程序目录:
  1. libmcctest01.h
  2. libmcctest01.lib
  3. libmcctest01.dll
  4. libmcctest01.ctf
复制代码
接下来的任务就是如何在fortran程序中调用libmcctest01.dll。暂告一段落,在下面帖子中介绍。
回复 不支持

使用道具 举报

发表于 2008-3-21 21:52:56 | 显示全部楼层 来自 新加坡
Fortran无法直接使用动态链接库(或者有些版本的fortran编译器,比如PGI,或Visual Fortran等有相关的扩展,不过我不了解)。长话短说,在fortran程序中,我们可以通过调用c语言的方式间接调用dll,具体的做法是我们为调用dll中的函数,另外在写一个和fortran兼容的c或c++语言的wrapper函数。这里牵涉到fortran和c/c++的混合编程,主要有两点需要注意的:
  1. 1. Fortran程序中函数的参数是以地址的方式传递的。也就是说类似于
  2. subroutine foo(x, y, z)
  3. real x, y, z

  4. 其等效的c语言函数声明则类似
  5. void foo( float* x, float* y, float* z);

  6. 2. 有些fortran编译器比如g77,在编译函数后会在函数名的后面在多加一个下划线“_",也就是上面的subroutine foo编译后,函数名就变成了foo_。换句话说,如果在fortran中用
  7. call foo(...)
  8. 调用foo子函数,其实是找foo_。
复制代码
说起来好像挺烦的,不过做几次练习以后就熟悉了。

下面给出针对于我们的例子,也就是libmcctest01.dll中mcctest01函数的调用,一个可行的C++语言的wrapper函数:
  1. // File: mcctest01wrap.cpp
  2. // Description: A simple testing c++ souce file. Two functions
  3. // are defined, which will be called in a FORTRAN 77 code.
  4. //
  5. // History: Created on 16 January, 2006
  6. // Created by: Dong Weiguo
  7. //////////////////////////////////////////////////////////////

  8. #include "libmcctest01.h"

  9. // By default, most of fortran compilers would add an
  10. // undrescore at the end of function name
  11. // So let's emulate this bahavior
  12. extern "C" void mymccfunc_()
  13. {
  14.      libmcctest01Initialize();
  15.          mlxMcctest01(0, NULL, 0, NULL);
  16.          std::cout << "Press any key to quit!" << std::endl;
  17.          getchar();
  18.      libmcctest01Terminate();
  19. }


  20. // Another way to deal with this underscore thing is to
  21. // use some compiler flag to disable it. For example, we
  22. // can use "-fno-underscoring -fno-second-underscore" for
  23. // g77.
  24. extern "C" void mymccfunc()
  25. {
  26.      libmcctest01Initialize();
  27.      mlxMcctest01(0, NULL, 0, NULL);
  28.      libmcctest01Terminate();
  29. }
复制代码
这样,我们只要在fortran程序中调用某个wrapper函数,比如mymccfunc_就可以了。下面是这个例子的fortran主程序:
  1. C      A test program to demonstrate how to call c++
  2. C      functions from a Fortran program.
  3. C      Synopsis: f77cpptst
  4. C      History: 16 January, 2006
  5. C      Created by: Dong Weiguo

  6.        program f77cpptst
  7.       
  8.        call mymccfunc()
  9.   
  10.        stop
  11.        end
复制代码
可以看出,程序非常简单,就是调用wrapper函数。接下来就开始介绍如何编译我们的例子。

[ 本帖最后由 taohe 于 2008-3-21 22:14 编辑 ]
回复 不支持

使用道具 举报

发表于 2008-3-21 22:04:28 | 显示全部楼层 来自 新加坡
在这个例子中我用一个Makefile,通过调用gnu-make来实现例子程序的编译。这样作的好处是可方便的移植到其他平台,比如Linux(如果有时间,我再介绍一下在Linux上完成这个例子)。
  1. # makefile for f77mcctst on Windows by using MinGW

  2. CC =
  3. G77 = i:\mingw\bin\gfortran-sjlj.exe
  4. CFLAGS = -Wall -g -Ih:\MATLABr2007b\extern\include
  5. FFLAGS = #-fno-underscoring -fno-second-underscore
  6. LDFLAGS = -LH:\MATLABr2007b\extern\lib\win32\microsoft

  7. MYEXE = f77mcctst.exe
  8. MYOBJS = f77mcctst.o mcctest01wrap.o

  9. #default target = all
  10. all :  $(MYEXE)

  11. $(MYEXE) : $(MYOBJS)
  12.         $(G77) -o $(MYEXE) $(MYOBJS) libmcctest01.lib mclmcrrt.lib  $(LDFLAGS) -lm -lstdc++
  13.         
  14. mcctest01wrap.o : mcctest01wrap.cpp
  15.         g++-sjlj -c $(CFLAGS) mcctest01wrap.cpp

  16. f77mcctst.o : f77mcctst.for
  17.         $(G77) -c $(FFLAGS) f77mcctst.for


  18. clean:
  19.         del *.o
  20.         del $(MYEXE)
复制代码
然后在DOS命令行运行如下命令进行编译:
  1. I:\dwg\fortran\f77mcc_r2007b>mingw32-make
复制代码
其中mingw32-make是我用的MinGW中的make命令。

附件是这个例子所有文件的打包。

【注意事项】
1. 如果用MinGW 的gcc/g77的话,我们需要修改matlab r2007b中给出的mclmcr.h,打包文件中有我改过的mclmcr.h,你们可以把系统自带的做一个拷贝,然后把附件中的mclmcr.h_updated拷贝成mclmcr.h。
2. 使用MinGW的主要原因是它可以免费获得。如果你用不同版本的编译器,或者matlab,请根据自己的情况作相应的修改。

[ 本帖最后由 taohe 于 2008-3-21 22:10 编辑 ]

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
回复 不支持

使用道具 举报

发表于 2008-3-21 22:14:45 | 显示全部楼层 来自 新加坡
在这个例子中我用一个Makefile,通过调用gnu-make来实现例子程序的编译。这样作的好处是可方便的移植到其他平台,比如Linux(如果有时间,我再介绍一下在Linux上完成这个例子)。
  1. # makefile for f77mcctst on Windows by using MinGW

  2. CC =
  3. G77 = i:\mingw\bin\gfortran-sjlj.exe
  4. CFLAGS = -Wall -g -Ih:\MATLABr2007b\extern\include
  5. FFLAGS = #-fno-underscoring -fno-second-underscore
  6. LDFLAGS = -LH:\MATLABr2007b\extern\lib\win32\microsoft

  7. MYEXE = f77mcctst.exe
  8. MYOBJS = f77mcctst.o mcctest01wrap.o

  9. #default target = all
  10. all :  $(MYEXE)

  11. $(MYEXE) : $(MYOBJS)
  12.         $(G77) -o $(MYEXE) $(MYOBJS) libmcctest01.lib mclmcrrt.lib  $(LDFLAGS) -lm -lstdc++
  13.        
  14. mcctest01wrap.o : mcctest01wrap.cpp
  15.         g++-sjlj -c $(CFLAGS) mcctest01wrap.cpp

  16. f77mcctst.o : f77mcctst.for
  17.         $(G77) -c $(FFLAGS) f77mcctst.for


  18. clean:
  19.         del *.o
  20.         del $(MYEXE)
复制代码
然后在DOS命令行运行如下命令进行编译:
  1. I:\dwg\fortran\f77mcc_r2007b>mingw32-make
复制代码
其中mingw32-make是我用的MinGW中的make命令。

评分

1

查看全部评分

回复 不支持

使用道具 举报

 楼主| 发表于 2008-3-24 18:17:39 | 显示全部楼层 来自 大连理工大学

回复 6# 的帖子

非常感谢,我去试试
回复 不支持

使用道具 举报

发表于 2008-3-24 20:35:53 | 显示全部楼层 来自 新加坡
原帖由 lyyzby 于 2008-3-24 18:17 发表
非常感谢,我去试试


后来我想起来,我以前贴过一个帖子,介绍如何在Fortran中调用matlab编译的库函数。下面是连接:
http://www.simwe.com/forum/viewt ... 0677&highlight=

不过那贴是以matlab6.5.1作为例子的,可以和这次的结合起来看。
回复 不支持

使用道具 举报

发表于 2008-3-25 14:39:50 | 显示全部楼层 来自 陕西西安
我想用matlab拟合曲线,以前没用过matlab,不知道是不是很难
回复 不支持

使用道具 举报

发表于 2008-3-25 21:45:43 | 显示全部楼层 来自 新加坡
原帖由 huiwei 于 2008-3-25 14:39 发表
我想用matlab拟合曲线,以前没用过matlab,不知道是不是很难


应该不是很难,它毕竟只是一个工具软件,而且又有大量的参考资料。不过也要注意到,它是个复杂的工具软件,所以在刚开始的时候,要花点功夫。
回复 不支持

使用道具 举报

发表于 2009-1-2 22:53:09 | 显示全部楼层 来自 广东广州
原帖由 taohe 于 2008-3-25 21:45 发表


应该不是很难,它毕竟只是一个工具软件,而且又有大量的参考资料。不过也要注意到,它是个复杂的工具软件,所以在刚开始的时候,要花点功夫。


不知taohe兄有否试过用1stopt来调用matlab生成的dll? 还有matlab生成的mat文件(NN网络)可否也能生成dll?
以前没有用过混合编程,现在想用1stopt优化matlab生成的dll,     问题可能比较幼稚。

[ 本帖最后由 geni 于 2009-1-2 23:31 编辑 ]
回复 不支持

使用道具 举报

发表于 2009-1-3 10:46:11 | 显示全部楼层 来自 新加坡
原帖由 geni 于 2009-1-2 22:53 发表


不知taohe兄有否试过用1stopt来调用matlab生成的dll? 还有matlab生成的mat文件(NN网络)可否也能生成dll?
以前没有用过混合编程,现在想用1stopt优化matlab生成的dll,     问题可能比较幼稚。



matlab产生的DLL就是一般的Win32 DLL文件,所以只要1stopt支持调用DLL文件,那么就是可行的。不过要注意matlab7.x编译的DLL文件在运行的目标电脑上需要MCR环境。

NN网络的训练有关的函数可能无法通过一般的编译技术编译成DLL文件,但是其他的,比如使用NN网络做预测都函数都是可以编译成DLL在其他程序中使用的。
回复 不支持

使用道具 举报

发表于 2009-2-25 10:20:01 | 显示全部楼层 来自 河北石家庄
本帖最后由 kokyo52 于 2009-2-25 10:54 编辑

我写了一点关于Matlab混合编程的东西,大家可以参考一下
http://forum.simwe.com/thread-865964-1-1.html
回复 不支持

使用道具 举报

发表于 2010-1-6 23:05:05 | 显示全部楼层 来自 浙江杭州
各位高手,我在调用MATLAB,如下运行:
>> mex-setup

Select a compiler:
[1] Lcc C version 2.4 in D:\MATLAB\sys\lcc
[2] Microsoft Visual C/C++ version 6.0 in C:\Program Files\Microsoft Visual Studio

[0] None

Compiler:
我安装的是cvf6.6,请问为什么MATLAB不识别,记得安装cvf6.6的时候环境变量好像有问题,难道真是环境变量的问题吗,还请taohe给以解答,非常感谢!
回复 不支持

使用道具 举报

发表于 2010-1-7 14:54:19 | 显示全部楼层 来自 浙江杭州
Matlab版本号是多少?

各位高手,我在调用MATLAB,如下运行:
>> mex-setup

Select a compiler:
[1] Lcc C version 2.4 in D:\MATLAB\sys\lcc
[2] Microsoft Visual C/C++ version 6.0 in C:\Program Files\Microsoft Visual Stu ...
yldpj 发表于 2010-1-6 23:05
回复 不支持

使用道具 举报

发表于 2010-1-8 16:08:31 | 显示全部楼层 来自 浙江杭州
15# messenger

MATLAB版本是7.0,但是只有0.99G,不知道是不是文件不全的原因还是啥的?
回复 不支持

使用道具 举报

发表于 2011-6-13 15:21:19 | 显示全部楼层 来自 江苏南京
不知道楼主还在关注这贴,下面给出一个在fortran中调用matlab编译生成的DLL的例子。

【试验环境】Windows 2003 server std,matlab r2007b,MinGW gcc 4.2 (sjlj)。Visual Studio 2005
【试验任务】实现在fortra ...
taohe 发表于 2008-3-21 21:35
taohe,还在吗?为什么我运行这段代码的时候会出错呢?

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
回复 不支持

使用道具 举报

发表于 2011-6-13 15:24:50 | 显示全部楼层 来自 江苏南京
Fortran无法直接使用动态链接库(或者有些版本的fortran编译器,比如PGI,或Visual Fortran等有相关的扩展,不过我不了解)。长话短说,在fortran程序中,我们可以通过调用c语言的方式间接调用dll,具体的做法是我们 ...
taohe 发表于 2008-3-21 21:52
回复 不支持

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Simapps系列直播

Archiver|小黑屋|联系我们|仿真互动网 ( 京ICP备15048925号-7 )

GMT+8, 2024-10-4 17:18 , Processed in 0.049515 second(s), 13 queries , Gzip On, MemCache On.

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表