【转载请注明出处】http://www.cnblogs.com/mashiqi

先上总结:

由于C/C++语言的函数输入输出参数的特点,可以将多个参数方便地传入一个函数中,但却不能方便地返回多个参数。要返回多个参数,就得用指针或者struct/class(其他的高招?)。但这些麻烦的地方在C程序的函数与函数之间是没有太大问题的,关键是不要在C与MATLAB的接口之处搞的太复杂。

但是,我们在写MATLAB代码的时候,由于变量的格式非常自由,所以我们往往都尽量把变量的格式设计成很comprehensible的形式。比如说,我写的这个能完成Adaboost算法功能的m函数adaboost_mashiqi(),它的返回值中既有向量,也有矩阵,还有结构体。这在C中看来是很复杂的,但却很直观,这些变量就该是这种形式的。甚至如果是多层树的话,还应该是链表呢!

这两段话的内容可以用如下这张图来表示。

解释一下这张图。最左边的是一个m文件,它准备调用一个用C/C++写的名为true_function()的函数。我们把这个函数的输入输出简单记为inputs和outputs,于是函数应该是这样的:

由于inputs和outputs都是MATLAB里面的变量们,所以它们很有可能是comprehensible的。到了mexFunction()后,首先要做的事情就是把这些comprehensible but not convenient的变量转换成C语言易于处理的convenient的变量,然后调用真正实现函数功能的true_function()函数去实现功能,最后再将这些convenient but not comprehensible的变量转换成合适与MATLAB的comprehensible的变量。

可是,这样做比那个不是最好的,因为mexFunction()中处理这些comprehensible but not convenient的变量可能相当麻烦。转换变量类型并非C/C++的优势,C/C++的优势在于对循环的处理极大的快于MATLAB!所以,我们有第二种方案,能避开C/C++的劣势,同时又保留C/C++的优势,这是一个两全其美的办法。请看下图:

此方案将参数转换的工作放到了MATLAB里面来做。这是绝对正确的一个方法,因为在MATLAB里面各变量之间的类型转换是相当自由的。我们来看看进行了这样的改变之后,整个过程变成了什么样。首先,主文件调用Interface()函数,参数传递都在MATLAB里面,很方便;进入Interface()函数后,在MATLAB平台上将各个变量转变为C/C++平台好处理的格式(比如说把结构体的各个成员变量分别独立传进去而不是把真个结构体作为一个整体传进去etc);现在到了mexFunction(),由于变量在Interface()里面已经经过了处理,在这里只需要再做一些trivial的处理就行了,然后直接调用true_function()来实现具体的功能。整个流程非常的easy!

当然,还有一些问题,比如在MATLAB中我们常常将一些控制整个算法参数的变量放进一个结构体变量options中,然后将这个结构体传入函数进行控制(比如算法最大迭代次数啊,收敛条件的epsilon大小啊等等)。这个options在上面这个框架里怎么实现呢?我在这个给出一个我的办法。首先,在Interface()之前调用options = OptionsSettings(…)函数,设定相应的控制变量,然后把这个options结构体变量随着inputs一起传入Interface()函数。在Interface()函数内部,将这个options结构体的各个成员变量单拿出来作为变量分别传入true_function()中,这样就可以了。

mexFunction()中一些函数总结

在mexFunction()刚开头,一般需要把存放在prhs[?]中的MATLAB格式的变量转换成C中的double, int等类型的变量,怎么做呢?如果prhs[0]中(也就是第一个input)是一个MATLAB中的scalar, vector或者matrix,那么就用mxGetPr()这个函数:

double *x_pointer = mxGetPr(prhs[0]);

对于MATLAB中的vector,通过x_pointer[0], x_pointer[1], x_pointer[2],…进行访问,对于MATLAB中的matrix,比如一个3x3的矩阵,则(1,1)的元素通过x_pointer[0]访问,(2,1)的元素通过x_pointer[1]访问,(1,2)的元素通过x_pointer[3+0]访问。对于MATLAB中的其他类型的数据,通过mxGetData()访问:

类型 *x_pointer = (类型*)mxGetData(prhs[0]);

mxGetData返回类型为void*,所以要进行类型转换。注意,mxGetPr()和mxGetData()的输入参数类型都是const mxArray*而不是mxArray*。

在mexFunction()刚开头,一般需要数据再次转回MATLAB能接受的类型,这时需要用到mxCreatDoubleMatrix()/mxCreatNumericMatrix()/mxCreatStructMatrix()等函数。举例:

plhs[0] = mxCreatDoubleMatrix(3,3,mxREAL);

double *p = mxGetPr(plhs[0]);

for(int i = 0; i < 10; i++) {

p[i] = i;

}

这样就完成了对plhs[0]的赋值,等返回MATLAB时,第一个output就会是(0:9)这个向量。没错,就是通过指向plhs[0]的指针p间接的像plhs[0]中赋值的。

博主给个example啊!

上面说的似乎都好抽象,这里给个链接,是我的一个代码,大家可以拿去看看,作为example,在我这个上面改改,练练手。但我这个代码也有一些瑕疵的。由于已经把整个代码都写完了,回过头来梳理的时候才发现这些问题,所以就懒得改了,下次注意的就是了。下面是我的代码的问题,写在这里,做个自己的一个记录吧。

关于我的这个代码中的变量tree的处理

在Adaboost_mashiqi()返回的结构体中,第一个成员变量tree本身也是一个结构体,不过上面已经说过,C函数之间传递参数的准则是as comprehensible as possible,所以这里处理tree的方法没有问题。问题出现在第二个出现tree的地方,就是返回给m文件的tree,这里的tree依然是一个结构体,这样就不太好了,一是变量格式转换起来不太方便,而是若以后想要给添加函数添加功能返回更多的变量,那这种情况下使用结构体也不方便。因此,可以在m文件和c文件中间在加一个m文件来完成"变量格式转换"这件事,这样既不会破环原m文件的格式,也能使得C文件的结构更容易编写与扩展。

如何在MATLAB和Visual Studio平台之间hybrid programming?

废话不多说,想知道如何设置Visual Studio来进行混合编程调试,点这里。另外,我用的版本是MATLAB R2012b和Visual Studio 2010,这两个是匹配的,若不是使用的这两个版本,这里在这里看您的两个版本是否匹配。

关于写程序的自我修养(/装逼捂脸中):

绝对不将就!

能优化就一定要优化;

能完善就一定要完善;

能写地更加优美就一定要能写地更加优美!

MATLAB与C/C++混合编程的一些总结的更多相关文章

  1. 【5.1送礼】国内第一部Matlab和C#.Net混合编程视频教程【免费】

                  本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新    Matlab和C#混合编程文章目录 :[目录]Matlab和C#混合编程文章目录 上一次写博客很久了 ...

  2. matlab和C/C++混合编程--Mex

    最近的项目需要matlab和C的混合编程,经过一番努力终于完成了项目要解决的问题.现在就将Mex的一些经验总结一下,当然只是刚刚开始,以后随着学习的深入继续添加.首先讲讲写Mex的一些常规规定,然后我 ...

  3. matlab和C/C++混合编程--Mex (六)参数传递

    最近的项目需要matlab和C的混合编程,经过一番努力终于完成了项目要解决的问题.现在就将Mex的一些经验总结一下,当然只是刚刚开始,以后随着学习的深入继续添加.首先讲讲写Mex的一些常规规定,然后我 ...

  4. matlab和C/C++混合编程--Mex (转载)

    matlab和C/C++混合编程--Mex 最近的项目需要matlab和C的混合编程,经过一番努力终于完成了项目要解决的问题.现在就将Mex的一些经验总结一下,当然只是刚刚开始,以后随着学习的深入继续 ...

  5. matlab和C/C++混合编程--调用opencv

    最近的我们已经将整个项目搭起来了,项目比较复杂.由于我们做的是检索系统,所以我们用asp.net(c#)做了网页,但是算法的实现是在matlab下,所以我们不得不用matlab生成动态链接库dll,然 ...

  6. Matlab和C语言混合编程,包含目录的设定

    如果.c文件不依赖于任何第三方库,那么mex编译很简单,只需要在matlab的命令行输入 mex test.c 即可. 但是如果这个c文件使用了第三方库文件,如opencv.gsl等等,那么就需要更改 ...

  7. matlab与VC6.0混合编程设置

    版本matlab 2009 和vc++6.0 SP6 步骤 1)  配置环境,新建一个VC工程,然后在VC界面的“工具->选项”的目录选项卡中的“include”中加入如下路径: 2)  D:\ ...

  8. MATLAB和C语言混合编程-----Matlab7.0 编译器设置

    (1) mex 命令设置 (a) 运行 Matlab ,在 Matlab 的命令窗口 (Command Window) 键入“ mex -setup ”命令后,按回车键,安装 Matlab 编译器: ...

  9. Matlab 2013a 和 VS2010 混合编程

    最近由于项目需求,某项目的算法是基于MATLAB完成的,在短时间内需要去调用算法功能.因此,基于MATLAB生成DLL, C 调用的方式完成. 环境:MATLAB 2013a + VS2010 + w ...

随机推荐

  1. oracle分析函数

    在工作中使用到的分析函数主要有两种,一个是sum () over (partition by ……order by ……)另外一个就是 lead(lag)over (|partition by|ord ...

  2. 在FireFox中安装Selenium IDE

    第二步:点击查看更多,查找Selenium IDE,安装 第三步:安装好后,在顶部的工具栏里点击"工具",弹出的选项框里出现Selenium IDE,安装完毕.

  3. 【Unity3D游戏开发】之游戏目录结构之最佳实践和优化 (十一)

    游戏目录结构之最佳实践 前置条件 1.多人协作开发,git管理 2.游戏不大,所有Scene合并到一起Scene中,eg.RoleScene.MapScene.StoreScene 3.Master一 ...

  4. 在mysql数据库原有字段后增加新内容

    update table set user=concat(user,$user) where xx=xxx; [注释]这个语法要求原来的字段值不能为null(可以为空字符''):

  5. [luogu2982][USACO10FEB]慢下来Slowing down(树状数组+dfs序)

    题目描述 Every day each of Farmer John's N (1 <= N <= 100,000) cows conveniently numbered 1..N mov ...

  6. js函数、变量提升(hoisting)

    其实我只是想复习下变量提升的,然后看到了函数提升,然后再看到了函数声明.函数表达式. 有必要怀着敬仰之心提及园子里的TOM大叔的解密命名函数表达式,不愧是大叔,好好地脑补了下基础知识. 在ECMASc ...

  7. hdu2243考研路茫茫——单词情结(ac+二分矩阵)

    链接 跟2778差不多,解决了那道题这道也不成问题如果做过基本的矩阵问题. 数比较大,需要用unsigned longlong 就不需要mod了 溢出就相当于取余 #include <iostr ...

  8. Android 利用SurfaceView进行图形绘制

    SurfaceView使用介绍 SurfaceView是View的一个特殊子类,它的目的是另外提供一个线程进行绘制操作. 要使用SurfaceView进行绘制,步骤如下: 1.用SurfaceView ...

  9. web应用程序测试方法和测试技术详述

    1.界面测试 现在一般人都有使用浏览器浏览网页的经历,用户虽然不是专业人员但是对界面效果的印象是很重要的.如果你注重这方面的测试,那么验证应用程序是否易于使用就非常重要了.很多人认为这是测试中最不重要 ...

  10. 第三节 构造一个简单的Linux系统MenuOS——20135203齐岳

    第三节 构造一个简单的Linux系统MenuOS By 20135203齐岳 Linux内核源代码 arch/ 支持不同cpu的源代码 Documentations/ 文档存储 init/ 内核启动相 ...