zoukankan      html  css  js  c++  java
  • 浅析将matlab函数编译成dll供Cpp调用的方法

    作者曾经实现过将matlab函数编译成dll供Cpp调用,这篇文章的目的是对新增的面向对象的的扩展mwArray进行讲解,matlab很容易和C/C++联合起来使用。

    以前做过matlab7与c++的混合编程:将matlab函数编译成dll给C++调用,从而加快开发的进度。但是今天在matlab2008b下面又做了一遍,发现matlab又改了很多东西,诸如增加了面向对象的的扩展mwArray,于是做笔记如下。

    (一) 总体概念

    matlab提供了丰富的程序接口,除了matlab最初的版本是用fortran写的之外,后来的版本都是用C写的,因此matlab很容易和C/C++联合起来使用。

    matlab有着丰富的库函数,将这些库函数直接编译成dll(windows下是dll,linux下是类似于dll的另外一个东西),给C调用,可以加快工程进度。

    步骤如下:

    1. 设置matlab的编译器,使用外部的VC或者gcc等编译器。

    2. 编译m文件成dll

    3. 设置VC等的继承环境,设置C需要用到的静态库和动态库

    4. 编写C调用dll

    下面以一个很简单的加法函数为例,说明在VC6和matlab2008b下,怎么做混合编程

    (二) 设置matlab编译器

    过程如下:

    1. 在matlab的command window里面敲入mex –setup,matlab会列出所有电脑上所有的编译器。

    2. 选择编译器,这里选择2,即VC6

    设置matlab编译器

    3.完成之后,敲入mbuild –setup,选择build工具,matlab会列出所有的build工具,同样选择VC6

    选择编译器

    (三) 编译m文件

    首先,写出matlab函数,一个很简单的加法函数,如下:

    1. function [c] = MyAdd(a, b);   
    2. c = a + b;  

    保存为MyAdd.m

    然后,进行编译,命令如下:

    mcc -W cpplib:libMyAdd -T link:lib MyAdd

    其中,mcc是matlab提供的编译命令(可以理解为gcc),对于这一点,matlab的帮助说明如下:

    -W lib:string link:lib

    其中-W是控制编译之后的封装格式,cpplib,是指编译成C++的lib,cpplib冒号后面是指编译的库的名字,-T表示目标,link:lib表示要连接到一个库文件的目标,目标的名字是后面的MyAdd,即你写的m函数的名字。

    运行完之后,你的目录下面,将会出现以下一些文件:

    libMyAdd.cpp

    libMyAdd.exp

    libMyAdd.dll

    libMyAdd.exports

    libMyAdd.h

    libMyAdd.prj

    libMyAdd_mcc_component_data.c

    mccExcludedFiles.log

    readme.txt

    具体每一个文件的意思,请查帮助,这里只说其中很有用的几个:

    libMyAdd.dll是编译好的动态库,MyAdd这个函数封装在里面,libMyAdd.h是对应的头文件,在C里面调用这个函数的时候,需要include这个头文件,在这个头文件的最后,你可以看到下面的内容:

    extern LIB_libMyAdd_CPP_API void MW_CALL_CONV MyAdd(int nargout, mwArray& c

    , const mwArray& a

    , const mwArray& b);

    这就是MyAdd的C函数的声明。

    nargout表示输出变量的个数

    a,b,c就是对应了m函数的几个变量

    注意,a,b,c三个变量的类型是mwArray,这是matlab提供的一个特殊的变量类型(在7.0的版本,编译之后,变量类型是mxArray)。mwArray是一个类,具体可以查帮助,当然后面也会讲到。

    (四) 设置VC环境

    有了上面的准备,需要设置VC环境,好让lib和dll能被成功的调用。

    1. 首先建立一个控制台工程(这个我就不详细讲了,太easy了)

    2. 然后,在tool-option-directory里面设置用到的lib和include头文件的位置

    首先是include头文件的位置,看最后一行(这个根据每一个人的安装目录可能不一样,自己去找吧)

    设置VC环境

    然后是lib的位置,不尽包括matlab的静态库的位置,还包括刚刚编译出来的lib的位置,见图的后面两个,不用我解释吧

    matlab的静态库的位置

    你可以打开这两个目录,看看里面到底有哪些头文件和lib,首先来讲,我们这里要用到的头文件包括:

    #include "mclmcr.h"

    #include "matrix.h"

    #include "mclcppclass.h"

    #include "libMyAdd.h"

    lib包括

    mclmcrrt.lib libmx.lib libmat.lib mclmcr.lib

    你可以到具体的路径下看一看,有没有上面几个lib和头文件

    路径设好了,需要制定具体用到的lib了,在project Setting-link-Object/library modules里面加入上面提到的几个lib(具体几个lib到底做什么用的,这里不讲了,看帮助,或者你试验删去几个lib能不能工作,就大概可以猜得 到他们是干什么的了)

    clip_image009

    3. 将编译好的dll复制到VC工程的Debug或者Release目录下,以使得dll可以被找到。

    (五) 写Cpp调用dll

    所有任务完成之后,开始写Cpp试验调用编译之后的函数了。

    首先,包含应有的头文件:

    1. #include "mclmcr.h"   
    2. #include "matrix.h"   
    3. #include "mclcppclass.h"   
    4. #include "libMyAdd.h"   
    5. #include   
    6. #include  

    然后,写main函数:

    1. int main(void)   
    2. {   
    3. double a = 6;   
    4. double b = 9;   
    5. double c;   
    6. // initialize lib,这里必须做初始化!   
    7. if( !libMyAddInitialize())   
    8. {   
    9. std::cout << "Could not initialize libMyAdd!" << std::endl;   
    10. return -1;   
    11. }   
    12. // 为变量分配内存空间,可以查帮助mwArray   
    13. mwArray mwA(1, 1, mxDOUBLE_CLASS); // 1,1表示矩阵的大小(所有maltab只有一种变量,就是矩阵,为了和Cpp变量接轨,设置成1*1的矩阵,mxDOUBLE_CLASS表示变量的精度)   
    14. mwArray mwB(1, 1, mxDOUBLE_CLASS);   
    15. mwArray mwC(1, 1, mxDOUBLE_CLASS);   
    16. // set data,不用我解释了吧,很简单的,调用类里面的SetData函数给类赋值   
    17. mwA.SetData(&a, 1);   
    18. mwB.SetData(&b, 1);   
    19. // using my add,掉我自己写的函数   
    20. MyAdd(1, mwC, mwA, mwB);   
    21. // get data,不用我解释了吧,很简单的,调用类里面的Get函数获取取函数返回值   
    22. c = mwC.Get(1, 1);   
    23. printf("c is %f\n", c);   
    24. // 后面是一些终止调用的程序   
    25. // terminate the lib   
    26. libMyAddTerminate();   
    27. // terminate MCR   
    28. mclTerminateApplication();   
    29. return 0;   
    30. }  

    运行结果如下:

    运行结果

  • 相关阅读:
    【算法学习笔记】27.动态规划 解题报告 SJTU OJ 1254 传手绢
    【算法学习笔记】26.扫描维护法 解题报告 SJTU OJ 1133 数星星
    【算法学习笔记】25.贪心法 均分纸牌问题的分析
    【算法学习笔记】24.记忆化搜索 解题报告 SJTU OJ 1002 二哥种花生
    【算法学习笔记】23.动态规划 解题报告 SJTU OJ 1280 整装待发
    【算法学习笔记】22.算法设计初步 二分查找 上下界判断
    【算法学习笔记】21.算法设计初步 求第k个数 划分法 快排法
    【算法学习笔记】20.算法设计初步 归并排序 求逆序数
    【算法学习笔记】19.算法设计初步 最大子列和问题的几种方法
    【算法学习笔记】18.暴力求解法06 隐式图搜索2 八数码问题 未启发
  • 原文地址:https://www.cnblogs.com/jeffkuang/p/2314252.html
Copyright © 2011-2022 走看看