Linux 下C与matlab 混编

1 概述

1.1 Matlab简介

MATLAB是美国MathWorks公司出品的商业数学软件,用于算法开发、数据可视化、数据分析以及数值计算的高级技术计算语言和交互式环境,主要包括MATLAB和Simulink两大部分。MATLAB应用非常之广泛!

MATLAB 亦可以与其他高级语言C/ C++/ C#/Java/Fortran等进行混合编程。

1.2 什么是Matlab引擎

所谓Matlab引擎(engine),是指一组Matlab提供的接口函数,支持C/C++、Fortran等语言,通过这些接口函数,用户可以在其它编程环境中实现对Matlab的控制。

2 启动Matlab前相关环境设置

2.1 matlab引擎依赖条件

matlab引擎依赖/bin/csh启动,所以不管你使用何种shell,都必须安装csh

#yum install chs    (centos/redhat平台)

#apt-get install chs  (ubuntu平台)

2.2 matlab引擎依赖的动态库文件目录必须在系统当前的库函数搜索路径中

即可以设置环境

LD_LIBRARY_PATH= /usr/local/matlab/bin/glnx86    (ps:32环境下)

LD_LIBRARY_PATH=/usr/local/matlab/bin/glnxa64    (ps:64 环境下)

2.3 用gcc或者g++ 编译

编写好的程序编译时需要指定头文件目录,链接时需要指定库文件目录,并且需要指定所需要的库文件

相关命令如下:

#gcc -I/usr/local/matlab/extern/include  -o matlab.o matlab.c

#gcc -L/usr/local/matlab/bin/glnx86 -Wl,-rpath,/usr/local/matlab/bin/glnx86 -o matlab matlab.o -leng -lmx

2.4 相关环境设置总结:

上述2.1  2.2  2.3对如何编译C与matlab 进行了说明,但是步骤较多,程序编译较为繁琐。因为我们可以通过一次环境变量的设置来达到这种目的。

export PATH=$PATH:"/usr/local/matlab/bin"

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:"/usr/local/matlab/bin/glnxa64"

export C_INCLUDE_PATH=$C_INCLUDE_PATH:"/usr/local/matlab/extern/include"

export LIBRARY_PATH=$LIBRARY_PATH:"/usr/local/matlab/bin/glnxa64"

把上述环境变量的设置写进文件名为xx.env的文件中,然后使用命令source执行

#source xx.env

执行完上述命令后就把所有的环境变量设置完毕。

接下来就可以用gcc/g++ 进行编译:

#gcc test.c -o test -leng -lmex -lmx

注:/usr/local/matlab/  此路径为Matlab安装时的路径,可根据实际情况进行变动。

3 Matlab与C的接口函数介绍

3.1 Matlab引擎的启动与关闭

engOpen-打开Matlab engine

函数声明:

Engine *engOpen(const char *startcmd);

参数startcmd是用来启动Matlab引擎的字符串参数为NULL。

函数返回值是一个Engine类型的指针,它是在engine.h中定义的engine数据结构。

EngClose-关闭Matlab 引擎

函数声明:

int engClose(Engine *ep);

参数ep代表要被关闭的引擎指针。

函数返回值为0表示关闭成功,返回1表示发生错误。

例如:通常用来打开/关闭Matlab引擎的代码如下:


Engine *ep; //定义Matlab引擎指针。

if (!(ep=engOpen(NULL))) //测试是否启动Matlab引擎成功。

{

perror("Can‘t start Matlab engine!" );

exit(1);

}

…………

engClose(ep); //关闭Matlab引擎。

3.2 创建和清除mxArray类型的数据

Matlab有很多种变量类型,对应于每种类型,基本上都有一个函数用于创建,但它们都有相同的数据结构,就是mxArray。

数组的建立采用mxCreatexxx形式的函数,例如新建一个double类型数组,可用函数mxCreateDoubleMatrix,

函数声明:

mxArray *mxCreateDoubleMatrix(int m, int n, mxComplexity ComplexFlag);

参数m和n为矩阵的函数和列数。ComplexFlag为常数,用来区分矩阵中元素是实数还是复数,取值分别为mxREAL和mxCOMPLEX。

例如,创建一个3行5列的二维实数数组,可用如下语句:


mxArray *T = mxCreateDoubleMatrix(3, 5, mxREAL);

对应的,要删除一个数组mxDestroyArray,该函数声明如下:

void mxDestroyArray(mxArray *array_ptr);

参数array_ptr为要删除的数组指针。

类似的创建函数还有:

函数声明:

mxArray *mxCreateString(const char *str);

创建一个字符串类型并初始化为str字符串。

一般的在C与Matlab交互中,以上两种类型就够了,其它类型数组的创建这里不再介绍。

3.3 管理mxArray的数据类型

3.3.1 管理mxArray数据大小

要获得mxArray数组每一维上元素的个数,可以用mxGetM和mxGetN函数。其中mxGetM用来获得数组第一维的元素个数,对于矩阵来说就是行数。

int mxGetM(const mxArray *array_ptr); //返回array_ptr对应数组第一维的元素个数(行数)

int mxGetN(const mxArray *array_ptr); //返回array_ptr对应数组其它维的元素个数,对于矩阵来说是列数。对于多维数组来说是从第2维到最后一维的各维元素个数的乘积。

要获得某一特定维的元素个数,则要用函数:

const int *mxGetDimensions(const mxArray *array_ptr);

该函数返回array_ptr各维的元素个数保存在一个int数组中返回。对于常用的矩阵来说,用mxGetM和mxGetN两个函数就可以了。

另外还可以通过mxGetNumberOfDimensions来获得数组的总的维数,用mxSetM、mxSetN设置矩阵的行数和列数,函数说明如下:

int mxGetNumberOfDimensions(const mxArray *array_ptr); //返回数组的维数

void mxSetM(mxArray *array_ptr, int m); //设置数组为m行

void mxSetN(mxArray *array_ptr, int n); //设置数组为n列

3.3.2 判断mxArray数组类型

在对mxArray类型的变量进行操作之前,可以验证以下其中的数组的数据类型,比如是否为double数组、整数、字符串、逻辑值等,以及是否为某种结构、类、或者是特殊类型,比如是否为空数组,是否为inf、NaN等。常见的判断函数有:

bool mxIsDouble(const mxArray *array_ptr);

bool mxIsComplex(const mxArray *array_ptr);

bool mxIsChar(const mxArray *array_ptr);

bool mxIsEmpty(const mxArray *array_ptr);

bool mxIsInf(double value);

…… ……

这些函数比较简单,不再解释。

3.3.3 管理mxArray数组的数据

对于常用的double类型的数组,可以用mxGetPr和mxGetPi两个函数分别获得其实部和虚部的数据指针,这两个函数的声明如下:

double *mxGetPr(const mxArray *array_ptr); //返回数组array_ptr的实部指针

double *mxGetPi(const mxArray *array_ptr); //返回数组array_ptr的虚部指针

这样,就可以通过获得的指针对mxArray类型的数组中的数据进行读写操作。例如可以用函数engGetVariable从Matlab工作空间读入 mxArray类型的数组,然后用mxGetPr和mxGetPi获得数据指针,对并其中的数据进行处理,最后调用engPutVariable函数将修 改后的数组重新写入到Matlab工作空间。

3.4 调用引擎时显示/隐藏Matlab主窗口

默认情况下,以engine方式调用Matlab的时候,会打开Matlab主窗口,可在其中随意操作。但有时也会干扰应用程序的运行,可用以下设置是否显示该窗口。

函数声明:

int engSetVisible(Engine *ep, bool value);

参数ep为打开的Matlab引擎指针,value为是否显示的标志,取值true(或1)表示显示Matlab窗口,取值false(或0)表示隐藏Matlab窗口。

函数返回值为0表示设置成功,为1表示有错误发生。

要获得当前Matlab窗口的显示/隐藏情况,可以调用函数:

函数声明:

int engGetVisible(Engine *ep, bool *value);

参数ep为打开的Matlab引擎指针,Value为用来保存显示/隐藏情况的变量(采用指针方式传递)。

函数返回值为0表示获取成功,为1表示有错误发生。

3.5 读写Matlab数据

3.5.1  从Matlab引擎工作空间中获取变量

函数声明:

mxArray *engGetVariable(Engine *ep, const char *name);

参数ep为打开的Matlab引擎指针,name为以字符串形式指定的数组名。

函数返回值是指向name数组的指针

3.5.2  向Matlab引擎工作空间写入变量

函数声明:

int engPutVariable(Engine *ep, const char *name, const mxArray *mp);

参数ep为打开的Matlab引擎指针,mp为指向被写入变量的指针,name为变量写入后在Matlab引擎工作空间中的变量名。

函数返回值为0表示写入变量成功,返回值为1表示发生错误。

3.6 向Matlab发送命令字符串

engEvalString-发送命令让Matlab执行。

函数声明:

int engEvalString(Engine *ep, Const char *string);

参数ep为函数engOpen返回的引擎指针,字符串string为要matlab执行的命令。

函数返回值为0表示成功执行,返回1说明执行失败(如命令不能被Matlab正确解释或Matlab引擎已经关闭了)。

3.7 获取Matlab命令窗口的输出

要在C中获得函数engEvalString发送的命令字符串被Matlab执行后在matlab窗口中的输出,可以调用engOUtputBuffer函数。

函数声明:

int engOutputBuffer(Engine *ep, char *p, int n);

参数ep为Matlab引擎指针,p为用来保存输出结构的缓冲区,n为最大保存的字符个数,通常就是缓冲区p的大小。该函数执行后,接下来的 engEvalString函数所引起的命令行输出结果会在缓冲区p中保存。如果要停止保存,只需调用代码:engOutputBuffer(ep, NULL, 0)。

4 C调用Matlab quadprog函数接口示例

/*
Author:bangzhu.li
Date:2014/09
Instruction:This software program is only used as an example, not an error exception handling.
E-mail:[email protected]
*/
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#include"engine.h"
#include<string.h>
int main(int argc,char** argv)
{
   Engine *ep;
   if (!(ep = engOpen("\0"))) //启动matlab 引擎
   {

      fprintf(stderr, "\nCan't start MATLAB engine\n");

      return EXIT_FAILURE;
   }
   engSetVisible(ep,false);
   mxArray *H = NULL, *f = NULL, *A = NULL, *b = NULL, *lb = NULL,*x = NULL;
   H = mxCreateDoubleMatrix(2, 2, mxREAL);
   f = mxCreateDoubleMatrix(2, 1, mxREAL);
   A = mxCreateDoubleMatrix(3, 2, mxREAL);
   b = mxCreateDoubleMatrix(3, 1, mxREAL);
   lb = mxCreateDoubleMatrix(2,1, mxREAL);
   x  = mxCreateDoubleMatrix(2,1, mxREAL);

   double HH[2][2]={1,-1,-1,2};
   double ff[2][1]={-2,-6};
   double AA[3][2]={1,1,-1,2,2,1};
   double bb[3][1]={2,2,3};
   double llbb[2][1]={0,0};
   double xx[2][1]={0,0};
   //把C数组转换为Matlab数组
   memcpy((void *)mxGetPr(H), (void *)HH, sizeof(double)*2*2);
   memcpy((void *)mxGetPr(f), (void *)ff, sizeof(double)*2*1);
   memcpy((void *)mxGetPr(A), (void *)AA, sizeof(double)*3*2);
   memcpy((void *)mxGetPr(b), (void *)bb, sizeof(double)*3*1);
   memcpy((void *)mxGetPr(lb), (void *)llbb,sizeof(double)*2*1);
   memcpy((void *)mxGetPr(x), (void *)xx,sizeof(double)*2*1);
   //把数组变量写入Matlab环境中
   engPutVariable(ep, "H", H);
   engPutVariable(ep, "f",f);
   engPutVariable(ep,"A",A);
   engPutVariable(ep,"b",b);
   engPutVariable(ep,"lb",lb);
   engPutVariable(ep,"x",x);
  //执行字符串命令
   int ret1 = engEvalString(ep,"H = [1 -1; -1 2];");
   int ret2 = engEvalString(ep,"f = [-2; -6];");
   int ret3 = engEvalString(ep,"A = [1 1; -1 2; 2 1];");
   int ret4 = engEvalString(ep,"b = [2; 2; 3];");
   int ret5 = engEvalString(ep,"lb = zeros(2,1);");
   int ret6 = engEvalString(ep,"[x] = quadprog(H,f,A,b,[],[],lb,[],[]);");

   char p[256]={0};
   char p1[256]={0};

   char* ans = "disp(x(1,1));";
   char* ans2 = "disp(x(2,1));";
   engOutputBuffer(ep,p,240);
   engEvalString(ep,ans);
   printf("p:%s\n",p);
   engOutputBuffer(ep,p1,240);
   engEvalString(ep,ans2);
   printf("p1:%s,\n",p1);
   mxDestroyArray(H);
   mxDestroyArray(f);
   mxDestroyArray(A);
   mxDestroyArray(b);
   mxDestroyArray(x);
   engClose(ep);
   return 0;
}
 
时间: 2024-10-05 23:59:34

Linux 下C与matlab 混编的相关文章

Linux下的TeXlive 2015 中文问题

据说可实现Linux下TeXlive中英混排的方法: 1. 本方法来自http://seisman.info/mini-template-for-xeCJK.html xeCJK + xeLaTeX,这大概是目前为止最优的中文解决方案. \documentclass{article} \usepackage{xeCJK} xeCJK将默认使用TeXLive自带的Fandole字体.要能够编译通过,需要将TeXLive自带的中文字体安装到系统中,最简单的办法是在~/.fonts目录下建一个软链接:

Matlab与C混编的介绍

原本写给一个朋友的,帮助她入门matlab与C混编的 >#####环境: * Matlab:MATLAB R2013a * C编译器VC++2012 === #####配置环境: 在**Matlab**命令行下输入: **step.1** ``` mex -setup ``` --- **step.2** 你也可以使用: ``` help mex ``` 查看更多信息 --- **step.3** 按提示安装C编译器 --- **step.4** 编写**c-mex**文件 可使用 ``` ed

Matlab + VS | Matlab2014a + VS2010 Win7 混编调试

Matlab在处理矩阵运算等数学类操作时很方便,但是在循环处理上效率相较VS低了很多,所以经常会用到mex对Matlab的.m混编C文件,调用C函数,提高代码运行效率.以上是我的一点粗浅的理解,欢迎大家补充. 要进行Matlab和C混编,首先需要安装Matlab和VS或VC(Windows系统).我软件的版本是Matlab2014a和VS2010,只要可以互相兼容调用,编译器的版本倒不是区别很大. 下面介绍一个Matlab通过Mex混编C的简单例子.代码主要功能是输入数组b和整数a,输出数组c的

在vs 2015环境下,c语言和汇编混编操作简析(更新中......)

在VS 2015环境下如何混编. 在新建工程里也会发现了很多问题, 应用程序类型分为:windows应用程序,控制台应用程序,DLL,静态库 静态库: 静态库是指在我们的应用中,有一些公共代码是需要反复使用,就把这些代码编译为"库"文件:在链接步骤中,连接器将从库文件取得所需的代码,复制到生成的可执行文件中的这种库. 程序编译一般需经预处理.编译.汇编和链接几个步骤.静态库特点是可执行文件中包含了库代码的一份完整拷贝:缺点就是被多次使用就会有多份冗余拷贝. 静态库和动态库是两种共享程序

Linux下安装Matlab

在windows下安装matlab是一件轻松的事情.因为windows解压,找到exe,点击,就可以进入图形界面,然后按照指引安装即可. linux下,则需要麻烦一点点.不过,也还好. 1. 下载一个matlab的iso包.很多地方都有这种资源的下载,如一些bt站,多快好省. 2. 使用命令把iso包挂在成为一个盘.iso本来就是虚拟光驱的概念,所以理所当然要用光驱的做法去打开它 mount -o loop /path/to/R2014b_glnxa64_withcrack.iso /mnt 例

Ubantu/Linux下安装Matlab

Ubantu版本:14.04 Matlab版本:2014a 安装Matlab2014a 1.下载好Mathworks.Matlab.R2014a.Unix.rar:http://pan.baidu.com/s/1c0GSxhQ 解压缩至Mathworks.Matlab.R2014a.Unix.iso,再解压缩至Mathworks.Matlab.R2014a.Unix. 也可直接下载Mathworks.Matlab.R2014a.Unix.iso,这样解压缩一次至Mathworks.Matlab.

MATLAB在Linux下的安装方法(待尝试)

有的,windows下,linux下我都用过,matlab的linux版图形界面使用的而是java,操作没有windows版的流畅,或多或少还有点问题,总之,感觉没有windows版好用,同版本的功能都是一样的,据说linux内核效率较高,跑matlab比windows快,但我没感觉出来. 以下是我的安装方法(注意你的matlab版本):软件下载地址:ftp://soft.hit.edu.cn/software/Science/Mathworks.Matlab/MatlabR13Unix/打开终

linux下c图形化编程之gtk+2.0简单学习

在linux下想做一个图形化的界面,然后自己选择使用gtk+2.0来进行编辑,我的电脑已经安装过gtk+2.0了,所以就在网上找了一个安装方法,结果未测试,大家有安装问题可以说下,一起探讨下. 1.安装gcc/g++/gdb/make 等基本编程工具 sudo apt-get install build-essential 2.安装 libgtk2.0-dev libglib2.0-dev 等开发相关的库文件 sudo apt-get install gnome-core-devel 3.用于在

【转】Linux下的多线程编

作者:gnuhpc 出处:http://www.cnblogs.com/gnuhpc/原文链接:http://www.cnblogs.com/gnuhpc/archive/2012/12/07/2807484.html 本文作者: 姚继锋 (2001-08-11 09:05:00) 黄鹏程(2009-03-13) converse (2009-01-15) 1 引言 线程(thread)技术早在60年代就被提出,但真正应用多线程到操作系统中去,是在80年代中期,solaris是这方面的佼佼者.传