MATLAB与C/C++混合编程的一些总结
【转载请注明出处】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++混合编程的一些总结的更多相关文章
- 【5.1送礼】国内第一部Matlab和C#.Net混合编程视频教程【免费】
本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新 Matlab和C#混合编程文章目录 :[目录]Matlab和C#混合编程文章目录 上一次写博客很久了 ...
- matlab和C/C++混合编程--Mex
最近的项目需要matlab和C的混合编程,经过一番努力终于完成了项目要解决的问题.现在就将Mex的一些经验总结一下,当然只是刚刚开始,以后随着学习的深入继续添加.首先讲讲写Mex的一些常规规定,然后我 ...
- matlab和C/C++混合编程--Mex (六)参数传递
最近的项目需要matlab和C的混合编程,经过一番努力终于完成了项目要解决的问题.现在就将Mex的一些经验总结一下,当然只是刚刚开始,以后随着学习的深入继续添加.首先讲讲写Mex的一些常规规定,然后我 ...
- matlab和C/C++混合编程--Mex (转载)
matlab和C/C++混合编程--Mex 最近的项目需要matlab和C的混合编程,经过一番努力终于完成了项目要解决的问题.现在就将Mex的一些经验总结一下,当然只是刚刚开始,以后随着学习的深入继续 ...
- matlab和C/C++混合编程--调用opencv
最近的我们已经将整个项目搭起来了,项目比较复杂.由于我们做的是检索系统,所以我们用asp.net(c#)做了网页,但是算法的实现是在matlab下,所以我们不得不用matlab生成动态链接库dll,然 ...
- Matlab和C语言混合编程,包含目录的设定
如果.c文件不依赖于任何第三方库,那么mex编译很简单,只需要在matlab的命令行输入 mex test.c 即可. 但是如果这个c文件使用了第三方库文件,如opencv.gsl等等,那么就需要更改 ...
- matlab与VC6.0混合编程设置
版本matlab 2009 和vc++6.0 SP6 步骤 1) 配置环境,新建一个VC工程,然后在VC界面的“工具->选项”的目录选项卡中的“include”中加入如下路径: 2) D:\ ...
- MATLAB和C语言混合编程-----Matlab7.0 编译器设置
(1) mex 命令设置 (a) 运行 Matlab ,在 Matlab 的命令窗口 (Command Window) 键入“ mex -setup ”命令后,按回车键,安装 Matlab 编译器: ...
- Matlab 2013a 和 VS2010 混合编程
最近由于项目需求,某项目的算法是基于MATLAB完成的,在短时间内需要去调用算法功能.因此,基于MATLAB生成DLL, C 调用的方式完成. 环境:MATLAB 2013a + VS2010 + w ...
随机推荐
- Redis哈希表的实现要点
Redis哈希表的实现要点 哈希算法的选择 针对不同的key使用不同的hash算法,如对整型.字符串以及大小写敏感的字符串分别使用不同的hash算法: 整型的Hash算法使用的是Thomas Wang ...
- JQuery对表格进行排序
添加相关jar <script type="text/javascript" src="jquery-1.1.3.pack.js"></scr ...
- win10离线安装.net framework 3.5
1.挂载win10系统镜像 2.执行命令 Dism /online /enable-feature /featurename:NetFX3 /All /Source:I:\sources\sxs /L ...
- static(静态、修饰符)
static(静态.修饰符) static修饰成员变量时:static修饰成员变量时,那么该成员变量的数据就是一个共享的数据. 静态成员变量的访问方式: 方式一: 使用对象进行访问. 对象.属性名 方 ...
- iOS开发 百度坐标转火星坐标
- (CLLocationCoordinate2D)hhTrans_GCGPS:(CLLocationCoordinate2D)baiduGps { const double x_pi = 3.141 ...
- JDK注解替代Hibernate的Entity映射
1.在entity(实体类)模块中使用注解 1_1.注解的位置出现在 [类定义的前面] 和 [属性的get方法前面] [属性的get方法前面] Java代码: package app.entity; ...
- Python学习笔记只列表和元组
一.成员资格 1.检查某个字符是否在某个字符串中:'a' in 'absent' 2.获取数组的长度.最大.最小值: numbers=[100,54,345] len(numbers) //长度 ma ...
- zju 1002
// zju 1002 // #include "stdafx.h" #include <string> #include <iostream> using ...
- WIN7 java7 环境变量配置
1 首先要搞清楚,java可能安装了两个部分,一个叫JDK,一个叫jre.其中jre若已经安装了,那么在安装JDK的时候,就不要放在默认的C:\Program File\java\XXX目录.最好另起 ...
- PHP二次开发discuz3.2最新体验
康盛官方于6月4号发布了discuz3.2的正式版,因为这两天一直忙于一个项目,一直没来的及体验,现在抽时间总算是装上了,也体验一把. 根据官方说明:Discuz! X3.2 在继承和完善 Discu ...