Matlab C混合编程
- #include "mex.h"
- void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
- {
- mexPrintf("hello,world!\n");
- }
假设你把hello.c放在了C:\TEST\下,在Matlab里用CD C:\TEST\ 将当前目录改为C:\TEST\(注意,仅将C:\TEST\加入搜索路径是没有用的)。现在敲:
mex hello.c
如果一切顺利,编译应该在出现编译器提示信息后正常退出。如果你已将C:\TEST\加入了搜索路径,现在键入hello,程序会在屏幕上打出一行:hello,world!
nlhs:输出参数数目
plhs:指向输出参数的指针
nrhs:输入参数数目
例如,使用
[a,b]=test(c,d,e)
调用mex函数test时,传给test的这三个参数分别是 prhs[0]=c ,prhs[1]=d ,prhs[2]=e
当函数返回时,将会把你放在plhs[0],plhs[1]里的地址赋给a和b,达到返回数据的目的。
细心的你也许已经注意到,prhs[i]和plhs[i]都是指向类型mxArray类型数据的指针。 这个类型是在mex.h中定义的,事实上,在Matlab里大多数数据都是以这种类型存在。当然还有其他的数据类型,可以参考Apiguide.pdf里的介绍。
- //hello.c 2.0
- #include "mex.h"
- void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
- {
- int i;
- i=mxGetScalar(prhs[0]);
- if(i==1)
- mexPrintf("hello,world!\n");
- else
- mexPrintf("大家好!\n");
- }
将这个程序编译通过后,执行hello(1),屏幕上会打出:
hello,world!
而hello(0)将会得到:
大家好!
现在,程序hello已经可以根据输入参数来给出相应的屏幕输出。在这个程序里,除了用到了屏幕输出函数mexPrintf(用法跟c里的printf函数几乎完全一样)外,还用到了一个函数:mxGetScalar,调用方式如下:
i=mxGetScalar(prhs[0]);
"Scalar"就是标量的意思。在Matlab里数据都是以数组的形式存在的,mxGetScalar的作用就是把通过prhs[0]传递进来的mxArray类型的指针指向的数据(标量)赋给C程序里的变量。这个变量本来应该是double类型的,通过强制类型转换赋给了整形变量i。既然有标量,显然还应该有矢量,否则矩阵就没法传了。看下面的程序:
- //hello.c 2.1
- #include "mex.h"
- void mexFunction(int nlhs, mxArray *plhs[],
- int nrhs, const mxArray *prhs[])
- {
- int *i;
- i=mxGetPr(prhs[0]); //prhs是一个指针数组(每一个是一个指针),所以返回一个指针
- if(i[0]==1)
- mexPrintf("hello,world!\n");
- else
- mexPrintf("大家好!\n");
- }
这样,就通过mxGetPr函数从指向mxArray类型数据的prhs[0]获得了指向double类型的指针。
但是,还有个问题,如果输入的不是单个的数据,而是向量或矩阵,那该怎么处理呢 ?通过mxGetPr只能得到指向这个矩阵的指针,如果我们不知道这个矩阵的确切大小,就 没法对它进行计算。
为了解决这个问题,Matlab提供了两个函数mxGetM和mxGetN来获得传进来参数的行数 和列数。下面例程的功能很简单,就是获得输入的矩阵,把它在屏幕上显示出来:
- //show.c 1.0
- #include "mex.h"
- #include "mex.h"
- void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
- {
- double *data;
- int M,N;
- int i,j;
- data=mxGetPr(prhs[0]); //获得指向矩阵的指针
- M=mxGetM(prhs[0]); //获得矩阵的行数
- N=mxGetN(prhs[0]); //获得矩阵的列数
- for(i=0;i<M;i++)
- { for(j=0;j<N;j++)
- mexPrintf("%4.3f ",data[j*M+i]);
- mexPrintf("\n");
- }
- }
编译完成后,用下面的命令测试一下:
- a=1:10;
- b=[a;a+1];
- show(a)
- show(b)
- // 获取维度个数
- numOfDim = mxGetNumberOfDimensions(pArray);
- // 获取维度数组
- Dims = mxGetDimensions(pArray);
需要注意的是,在Matlab里,矩阵第一行是从1开始的,而在C语言中,第一行的序数为零,Matlab里的矩阵元素b(i,j)在传递到C中的一维数组data后对应于data[j*M+i] 。 输入数据是在函数调用之前已经在Matlab里申请了内存的,由于mex函数与Matlab共用同一个地址空间,因而在prhs[]里传递指针就可以达到参数传递的目的。但是,输出参数却需要在mex函数内申请到内存空间,才能将指针放在plhs[]中传递出去。由于返回指针类型必须是mxArray,所以Matlab专门提供了一个函数:mxCreateDoubleMatrix来实现内存的申请,函数原型如下:
mxArray *mxCreateDoubleMatrix(int m, int n, mxComplexity ComplexFlag)
m:待申请矩阵的行数
n:待申请矩阵的列数
为矩阵申请内存后,得到的是mxArray类型的指针,就可以放在plhs[]里传递回去了。但是对这个新矩阵的处理,却要在函数内完成,这时就需要用到前面介绍的mxGetPr。使用 mxGetPr获得指向这个矩阵中数据区的指针(double类型)后,就可以对这个矩阵进行各种操作和运算了。下面的程序是在上面的show.c的基础上稍作改变得到的,功能是将输出处理后的元素:
- //reverse.c 1.0
- #include "mex.h"
- void mexFunction(int nlhs, mxArray *plhs[],
- int nrhs, const mxArray *prhs[])
- {
- double *inData;
- double *outData;
- int M,N;
- int i,j;
- inData=mxGetPr(prhs[0]);
- M=mxGetM(prhs[0]);
- N=mxGetN(prhs[0]);
- plhs[0]=mxCreateDoubleMatrix(M,N,mxREAL);
- outData=mxGetPr(plhs[0]);
- for(i=0;i<M;i++)
- for(j=0;j<N;j++)
- outData[j*M+i]=inData[(N-1-j)*M+i];
- }
当然,Matlab里使用到的并不是只有double类型这一种矩阵,还有字符串类型、稀疏矩阵、结构类型矩阵等等,并提供了相应的处理函数。本文用到编制mex程序中最经常遇到的一些函数,其余的详细情况清参考Apiref.pdf。
通过前面两部分的介绍,大家对参数的输入和输出方法应该有了基本的了解。具备了这些知识,就能够满足一般的编程需要了。但这些程序还有些小的缺陷,以前面介绍的re由于前面的例程中没有对输入、输出参数的数目及类型进行检查,导致程序的容错性很差,以下程序则容错性较好
- #include "mex.h"
- void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
- {
- double *inData;
- double *outData;
- int M,N;
- //异常处理
- //异常处理
- if(nrhs!=1)
- mexErrMsgTxt("USAGE: b=reverse(a)\n");
- if(!mxIsDouble(prhs[0]))
- mexErrMsgTxt("the Input Matrix must be double!\n");
- inData=mxGetPr(prhs[0]);
- M=mxGetM(prhs[0]);
- N=mxGetN(prhs[0]);
- plhs[0]=mxCreateDoubleMatrix(M,N,mxREAL);
- outData=mxGetPr(plhs[0]);
- for(i=0;i<M;i++)
- for(j=0;j<N;j++)
- outData[j*M+i]=inData[(N-1-j)*M+i];
- }
在上面的异常处理中,使用了两个新的函数:mexErrMsgTxt和mxIsDouble。MexErrMsgTxt在给出出错提示的同时退出当前程序的运行。MxIsDouble则用于判断mxArray中的数据是否double类型。当然Matlab还提供了许多用于判断其他数据类型的函数,这里不加详述。
需要说明的是,Matlab提供的API中,函数前缀有mex-和mx-两种。带mx-前缀的大多是对mxArray数据进行操作的函数,如mxIsDouble,mxCreateDoubleMatrix等等。而带mx前缀的则大多是与Matlab环境进行交互的函数,如mexPrintf,mxErrMsgTxt等等。了解了这一点,对在Apiref.pdf中查找所需的函数很有帮助。
常用的Mex函数一览表
MX Matrix Library
mwIndex (C and Fortran) |
Type for index values |
mwPointer (Fortran) |
Pointer type for platform |
mwSignedIndex (C and Fortran) |
Signed integer type for size values |
mwSize (C and Fortran) |
Type for size values |
mxAddField (C and Fortran) |
Field to structure array |
mxArray (C and Fortran) |
Type for MATLAB array |
mxArrayToString (C) |
Convert array to string |
mxAssert (C) |
Check assertion value for debugging purposes |
mxAssertS (C) |
Check assertion value without printing assertion text |
mxCalcSingleSubscript (C and Fortran) |
Offset from first element to desired element |
mxCalloc (C and Fortran) |
Allocate dynamic memory for array using MATLAB memory manager |
mxChar (C) |
Type for string array |
mxClassID (C) |
Enumerated value identifying class of array |
mxClassIDFromClassName (Fortran) |
Identifier corresponding to class |
mxComplexity (C) |
Flag specifying whether array has imaginary components |
mxCopyCharacterToPtr (Fortran) |
CHARACTER values from Fortran array to pointer array |
mxCopyComplex16ToPtr (Fortran) |
COMPLEX*16 values from Fortran array to pointer array |
mxCopyComplex8ToPtr (Fortran) |
COMPLEX*8 values from Fortran array to pointer array |
mxCopyInteger1ToPtr (Fortran) |
INTEGER*1 values from Fortran array to pointer array |
mxCopyInteger2ToPtr (Fortran) |
INTEGER*2 values from Fortran array to pointer array |
mxCopyInteger4ToPtr (Fortran) |
INTEGER*4 values from Fortran array to pointer array |
mxCopyPtrToCharacter (Fortran) |
CHARACTER values from pointer array to Fortran array |
mxCopyPtrToComplex16 (Fortran) |
COMPLEX*16 values from pointer array to Fortran array |
mxCopyPtrToComplex8 (Fortran) |
COMPLEX*8 values from pointer array to Fortran array |
mxCopyPtrToInteger1 (Fortran) |
INTEGER*1 values from pointer array to Fortran array |
mxCopyPtrToInteger2 (Fortran) |
INTEGER*2 values from pointer array to Fortran array |
mxCopyPtrToInteger4 (Fortran) |
INTEGER*4 values from pointer array to Fortran array |
mxCopyPtrToPtrArray (Fortran) |
Pointer values from pointer array to Fortran array |
mxCopyPtrToReal4 (Fortran) |
REAL*4 values from pointer array to Fortran array |
mxCopyPtrToReal8 (Fortran) |
REAL*8 values from pointer array to Fortran array |
mxCopyReal4ToPtr (Fortran) |
REAL*4 values from Fortran array to pointer array |
mxCopyReal8ToPtr (Fortran) |
REAL*8 values from Fortran array to pointer array |
mxCreateCellArray (C and Fortran) |
Unpopulated N-D cell array |
mxCreateCellMatrix (C and Fortran) |
Unpopulated 2-D cell array |
mxCreateCharArray (C and Fortran) |
Unpopulated N-D string array |
mxCreateCharMatrixFromStrings (C and Fortran) |
Create populated 2-D string array |
mxCreateDoubleMatrix (C and Fortran) |
2-D, double-precision, floating-point array initialized to 0 |
mxCreateDoubleScalar (C and Fortran) |
Scalar, double-precision array initialized to specified value |
mxCreateLogicalArray (C) |
N-D logical array initialized to false |
mxCreateLogicalMatrix (C) |
2-D, logical array initialized to false |
mxCreateLogicalScalar (C) |
Scalar, logical array |
mxCreateNumericArray (C and Fortran) |
Unpopulated N-D numeric array |
mxCreateNumericMatrix (C and Fortran) |
Numeric matrix initialized to 0 |
mxCreateSparse (C and Fortran) |
2-D unpopulated sparse array |
mxCreateSparseLogicalMatrix (C) |
Unpopulated 2-D, sparse, logical array |
mxCreateString (C and Fortran) |
Create 1-by-N array initialized to specified string |
mxCreateStructArray (C and Fortran) |
Unpopulated N-D structure array |
mxCreateStructMatrix (C and Fortran) |
Unpopulated 2-D structure array |
mxDestroyArray (C and Fortran) |
Free dynamic memory allocated by MXCREATE* functions |
mxDuplicateArray (C and Fortran) |
Make deep copy of array |
mxFree (C and Fortran) |
Free dynamic memory allocated by MXCALLOC, MXMALLOC, or MXREALLOC functions |
mxGetCell (C and Fortran) |
Contents of array cell |
mxGetChars (C) |
Pointer to character array data |
mxGetClassID (C and Fortran) |
Class of array |
mxGetClassName (C and Fortran) |
Class of array as string |
mxGetData (C and Fortran) |
Pointer to real data |
mxGetDimensions (C and Fortran) |
Pointer to dimensions array |
mxGetElementSize (C and Fortran) |
Number of bytes required to store each data element |
mxGetEps (C and Fortran) |
Value of EPS |
mxGetField (C and Fortran) |
Field value, given field name and index, into structure array |
mxGetFieldByNumber (C and Fortran) |
Field value, given field number and index, into structure array |
mxGetFieldNameByNumber (C and Fortran) |
Field name, given field number, in structure array |
mxGetFieldNumber (C and Fortran) |
Field number, given field name, in structure array |
mxGetImagData (C and Fortran) |
Pointer to imaginary data of array |
mxGetInf (C and Fortran) |
Value of infinity |
mxGetIr (C and Fortran) |
Sparse matrix IR array |
mxGetJc (C and Fortran) |
Sparse matrix JC array |
mxGetLogicals (C) |
Pointer to logical array data |
mxGetM (C and Fortran) |
Number of rows in array |
mxGetN (C and Fortran) |
Number of columns in array |
mxGetNaN (C and Fortran) |
Value of NaN (Not-a-Number) |
mxGetNumberOfDimensions (C and Fortran) |
Number of dimensions in array |
mxGetNumberOfElements (C and Fortran) |
Number of elements in array |
mxGetNumberOfFields (C and Fortran) |
Number of fields in structure array |
mxGetNzmax (C and Fortran) |
Number of elements in IR, PR, and PI arrays |
mxGetPi (C and Fortran) |
Imaginary data elements in array of type DOUBLE |
mxGetPr (C and Fortran) |
Real data elements in array of type DOUBLE |
mxGetProperty (C and Fortran) |
Value of public property of MATLAB object |
mxGetScalar (C and Fortran) |
Real component of first data element in array |
mxGetString (C and Fortran) |
String array to C-style string |
mxIsCell (C and Fortran) |
Determine whether input is cell array |
mxIsChar (C and Fortran) |
Determine whether input is string array |
mxIsClass (C and Fortran) |
Determine whether array is member of specified class |
mxIsComplex (C and Fortran) |
Determine whether data is complex |
mxIsDouble (C and Fortran) |
Determine whether mxArray represents data as double-precision, floating-point numbers |
mxIsEmpty (C and Fortran) |
Determine whether array is empty |
mxIsFinite (C and Fortran) |
Determine whether input is finite |
mxIsFromGlobalWS (C and Fortran) |
Determine whether array was copied from MATLAB global workspace |
mxIsInf (C and Fortran) |
Determine whether input is infinite |
mxIsInt16 (C and Fortran) |
Determine whether array represents data as signed 16-bit integers |
mxIsInt32 (C and Fortran) |
Determine whether array represents data as signed 32-bit integers |
mxIsInt64 (C and Fortran) |
Determine whether array represents data as signed 64-bit integers |
mxIsInt8 (C and Fortran) |
Determine whether array represents data as signed 8-bit integers |
mxIsLogical (C and Fortran) |
Determine whether array is of type mxLogical |
mxIsLogicalScalar (C) |
Determine whether scalar array is of type mxLogical |
mxIsLogicalScalarTrue (C) |
Determine whether scalar array of type mxLogical is true |
mxIsNaN (C and Fortran) |
Determine whether input is NaN (Not-a-Number) |
mxIsNumeric (C and Fortran) |
Determine whether array is numeric |
mxIsSingle (C and Fortran) |
Determine whether array represents data as single-precision, floating-point numbers |
mxIsSparse (C and Fortran) |
Determine whether input is sparse array |
mxIsStruct (C and Fortran) |
Determine whether input is structure array |
mxIsUint16 (C and Fortran) |
Determine whether array represents data as unsigned 16-bit integers |
mxIsUint32 (C and Fortran) |
Determine whether array represents data as unsigned 32-bit integers |
mxIsUint64 (C and Fortran) |
Determine whether array represents data as unsigned 64-bit integers |
mxIsUint8 (C and Fortran) |
Determine whether array represents data as unsigned 8-bit integers |
mxLogical (C) |
Type for logical array |
mxMalloc (C and Fortran) |
Allocate dynamic memory using MATLAB memory manager |
mxRealloc (C and Fortran) |
Reallocate dynamic memory using MATLAB memory manager |
mxRemoveField (C and Fortran) |
Remove field from structure array |
mxSetCell (C and Fortran) |
Value of one cell of array |
mxSetClassName (C) |
Convert structure array to MATLAB object array |
mxSetData (C and Fortran) |
Set pointer to data |
mxSetDimensions (C and Fortran) |
Modify number of dimensions and size of each dimension |
mxSetField (C and Fortran) |
Set structure array field, given structure field name and array index |
mxSetFieldByNumber (C and Fortran) |
Set structure array field, given field number and index |
mxSetImagData (C and Fortran) |
Imaginary data pointer for array |
mxSetIr (C and Fortran) |
IR array of sparse array |
mxSetJc (C and Fortran) |
JC array of sparse array |
mxSetM (C and Fortran) |
Number of rows in array |
mxSetN (C and Fortran) |
Set number of columns in array |
mxSetNzmax (C and Fortran) |
Set storage space for nonzero elements |
mxSetPi (C and Fortran) |
Set new imaginary data for array |
mxSetPr (C and Fortran) |
Set new real data for array |
mxSetProperty (C and Fortran) |
Set value of public property of MATLAB object |
MEX Library
mexAtExit (C and Fortran) |
Register function to call when MEX-function cleared or MATLAB software terminates |
mexCallMATLAB (C and Fortran) |
Call MATLAB function, user-defined function, or MEX-file |
mexCallMATLABWithTrap (C and Fortran) |
Call MATLAB function, user-defined function, or MEX-file and capture error information |
mexErrMsgIdAndTxt (C and Fortran) |
Display error message with identifier and return to MATLAB prompt |
mexErrMsgTxt (C and Fortran) |
Display error message and return to MATLAB prompt |
mexEvalString (C and Fortran) |
Execute MATLAB command in caller workspace |
mexEvalStringWithTrap (C and Fortran) |
Execute MATLAB command in caller workspace and capture error information |
mexFunction (C and Fortran) |
Entry point to C/C++ or Fortran MEX-file |
mexFunctionName (C and Fortran) |
Name of current MEX-function |
mexGet (C) |
Value of specified Handle Graphics property |
mexGetVariable (C and Fortran) |
Copy of variable from specified workspace |
mexGetVariablePtr (C and Fortran) |
Read-only pointer to variable from another workspace |
mexIsGlobal (C and Fortran) |
Determine whether variable has global scope |
mexIsLocked (C and Fortran) |
Determine whether MEX-file is locked |
mexLock (C and Fortran) |
Prevent clearing MEX-file from memory |
mexMakeArrayPersistent (C and Fortran) |
Make array persist after MEX-file completes |
mexMakeMemoryPersistent (C and Fortran) |
Make memory allocated by MATLAB software persist after MEX-function completes |
mexPrintf (C and Fortran) |
ANSI C PRINTF-style output routine |
mexPutVariable (C and Fortran) |
Array from MEX-function into specified workspace |
mexSet (C) |
Set value of specified Handle Graphics property |
mexSetTrapFlag (C and Fortran) |
Control response of MEXCALLMATLAB to errors |
mexUnlock (C and Fortran) |
Allow clearing MEX-file from memory |
mexWarnMsgIdAndTxt (C and Fortran) |
Warning message with identifier |
mexWarnMsgTxt (C and Fortran) |
Warning message |
参考:
http://blog.sciencenet.cn/blog-620659-579885.html
http://blog.csdn.net/raodotcong/article/details/6295859
Matlab C混合编程相关推荐
- Matlab.NET混合编程调用Figure窗体
原文:[原创]Matlab.NET混合编程调用Figure窗体 1.前言 做Matlab.NET混合编程好几年了,虽然Matlab很多函数忘记得差不多了,但基本的东西还是能熟练使用.特别是在C#调用M ...
- qt web混合编程_基于Qt与MATLAB的混合编程技术
摘要:在Qt雷达仿真系统中,数据处理及图形显示尤为重要.本文为此提出了一种Qt与MATLAB混合编程的方法.通过VC++和MATLAB混合编程技术,将MATLAB函数封装成动态链接库,Qt调用这个动态 ...
- 利用Matcom实现基于MATLAB的混合编程
利用Matcom实现基于MATLAB的混合编程 来源: 神经网络 作者:AI俱乐部 网友评论 0 条 浏览次数 42 <script> remark_look('re_look.php?c ...
- 基于引擎的matlab+vc混合编程的配置
前段时间在项目中做了一些关于基于引擎的vc+matlab混合编程的工作. 如果你是混合编程新手,我相信使用引擎的方式编程是比较简单快捷的一种方式. 当然这种方法也有其缺点,就是不能脱离matlab运行 ...
- matlab混合编程设置,matlab c++ 混合编程初始设置
以前做过matlab7与c++的混合编程:将m函数编译成dll给C++调用,从而加快开发的进度.但是今天在matlab2008b 下面又做了一遍,发现matlab又改了很多东西,诸如增加了面向对象的的 ...
- matlab r2012a win10,vs2010和Matlab R2012a 混合编程
注:Matlab r2010b及以后版本才支持vs2010, 之前版本中mbuild命令输入后可能会找不到vs2010编译器. 2.书写m文件 示例如下: function [ c ] = MyAdd ...
- Matlab C++混合编程 在VisualStudio下的编程 使用了Opencv库
某工程上需要在matlab上使用c++版本的opencv,之前使用的是版本配置是matlab2018和vs2018,而现在使用的是matlab2016和vs2015,不同matlab版本的调用c++代 ...
- VS2012和matlab 2010b混合编程之环境配
VC调用matlab Matlab是一个强大的数学计算/仿真工具,其内置了很多实用的现成的函数,而且我们经常也自己定义很多m函数.但在很多情况下,我们不得不使用VC编程.那么,如何在VC中利用matl ...
- Qt 调用MATLAB引擎混合编程
0.前言 C/C++调用MATLAB有三个方式:调用dll文件.调用exe可执行程序和调用Engin引擎. 第一种方式利用MATLAB Coder 将MATLAB代码生成C/C++代码和相关动态链接库 ...
最新文章
- 计算机组成原理—— 寻址方式
- mini2440:最简单的嵌入式linux驱动程序模块,mini2440:最简单的嵌入式Linux驱动程序模块 解决找不到mini2440……sample...
- 对象的单数组表示(用单数组实现链表-不一样的链表实现)
- 抛出异常–缓慢而丑陋
- mysql 除去列名打印_sql – 使用beeline时避免在列名中打印表名
- oracle sql 语句如何插入全年日期?
- Simulink之多重逆变电路
- linux目录架构及常用的基本命令
- Python入门学习笔记(2)
- Tbase 源码 (二)
- 米家推出新款石头机器人,扫拖一体,指哪去哪!
- Matlab将底色改为白色
- 同表父子关系 的SQL查询语句的写法
- CodeForces - 140C New Year Snowmen
- 基于TIVA库函数的TM4C1294XL使用笔记|TI单片机
- 某高校校园卡网站模拟登陆(php)
- 解决Java连接达梦数据库报For input string: “8“的问题
- BIM的真正基础是模型质量!
- 负基差会对股票量化对冲造成什么影响?
- Linux内存管理二(页表)
热门文章
- WINCE6.0更换桌面壁纸和图标
- 关键字static、const、volatile的作用
- EChart.js 简单入门
- ES6学习笔记--let和const
- 利用 Android Studio 和 Gradle 打包多版本APK
- 现在很多技术知识点缺乏来龙去脉的介绍
- 成幻Online Judge 1.00 Beta 正式发布 2007.6.22
- HTTP长连接、短连接
- java ssh过滤器_SSH中的过滤器,拦截器,监听器的一些基本认识
- 二分查找树性能分析(Binary Search Tree Performance Analysis)