注册 登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

ice1020502的博客

春天来了,冬天还会远吗?

 
 
 

日志

 
 

在VC中编译MATLAB可执行的mex程序  

2008-04-08 22:31:47|  分类: 专业知识 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

【转】http://blog.21ic.com/user1/1949/18224.html

在VC中编译mex程序

 

 一个mex程序实际上就是一个特别的DLL,它的输出函数为mexFunction。那么在VC中就可以用Project wizard建立一个DLL工程,并为指定输出为mexFunction.

1.       建立新的DLL工程

启动VC,选择菜单File/New,在Projects页面中选择MFC AppWizard(DLL),输入路径名和工程名,并单击OK按钮。

2.       选用静态链接的MFC类库

     在接下来的对话框中,选择使用静态链接MFC的DLL。这是因为,MATLAB使用了特殊片本的DLL文件mfc42.dll,并且放置在其程序中目录中,MATLAB必须使用自带的mfc42.dll文件,而这个文件与Windows系统目录中的相应文件是不兼容的,、用其中一个替换另一个,将会导致Windows系统工作不正,或MATLAB工作的不正常,严重时甚至造成MATLAB非法操作而异常退出。而用静态链接就不会出现这个问题。

3.       设定输出函数

AppWizard将会自动生成如下几个文件:

A.      Mextest.cpp

B.      Mextest.def

C.      Mextest.rc

D.     StdAfx.cpp   (前三个的名字与项目文件名有关)

     需要在mextest.def中指定该DLL文件的输出函数,也就是mexFunction。为此VC的Workspace栏中,单击“FileView”属性页,展开“Sourse File”栏,打开文件mextest.def,将其内容进行编辑,在“Exports”后面加入mexFunction一行。下面是编辑后的mextest.def文件的内容:

            ;mestest.def : Declares the module parameters for the DLL.

                    

                     LIBRARY   “mextest”

                     DESCRIPTION  ‘mextest Windows Dynamic Link Library’

                    

                     EXPORTS

                                   ; Explicit exports can go here

                     mexFunction

4.       环境设置

由于在编译和链接mex程序时,需要链接MATLAB提供的若干头文件,因此应该对这些文件的搜索路径进行指定。头文件在:

%MATLAB%exten\include

对VC6而言,库文件在:

%MATLAB%\extern\lib\win32\microsoft\msvc60

因此,需要将这两个目录加入到Vc的搜索路径中。通过选择菜单Tools/Options,打开选项对话框,在Directories属性页中,单击Include files,在列表中添入MATLAB头文件的目录,单击Library files,在列表中添入MATLAB库文件的目录。(注意“show directorles for:”中的切换 应为INCLUDE AND LIBRARY)

5.工程设置

   库文件的搜索路径指定了之后,还需要指定具体要连接哪些库文件。通过选择菜单Project/Settings,打开工程设置对话框,在Link属性页中,找到Object/library modules 编辑框,加入下面内容:

Libmx.lib  libmex.lib   libmatlbmx.lib   libmat.lib(在Matlab/extern/lib/borland中查找)

当然,如果MEX文件还用到其他的库文件,不管是MATLAB的,还是Windows系统的,或是自己编制的,都应该添加在这个编辑框中。

 

5.       添加代码

添加含有MEX功能代码,用CPP文件保存,并将文件加入工程,就可以编译和连接了。注意每个文件的开始都应该加上一行:

#i nclude “stdafx.h”

 

下面是一个简单的例子:

#i nclude "stdafx.h"

#i nclude "usb_matlab.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

//

// Note!

//

//  If this DLL is dynamically linked against the MFC

//  DLLs, any functions exported from this DLL which

//  call into MFC must have the AFX_MANAGE_STATE macro

//  added at the very beginning of the function.

//

//  For example:

//

//  extern "C" BOOL PASCAL EXPORT ExportedFunction()

//  {

//   AFX_MANAGE_STATE(AfxGetStaticModuleState());

//   // normal function body here

//  }

//

//  It is very important that this macro appear in each

//  function, prior to any calls into MFC.  This means that

//  it must appear as the first statement within the

//  function, even before any object variable declarations

//  as their constructors may generate calls into the MFC

//  DLL.

//

//  Please see MFC Technical Notes 33 and 58 for additional

//  details.

//

/////////////////////////////////////////////////////////////////////////////

// CUsb_matlabApp

BEGIN_MESSAGE_MAP(CUsb_matlabApp, CWinApp)

 //{{AFX_MSG_MAP(CUsb_matlabApp)

  // NOTE - the ClassWizard will add and remove mapping macros here.

  //    DO NOT EDIT what you see in these blocks of generated code!

 //}}AFX_MSG_MAP

END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////

// CUsb_matlabApp construction

CUsb_matlabApp::CUsb_matlabApp()

{

 // TODO: add construction code here,

 // Place all significant initialization in InitInstance

}

/////////////////////////////////////////////////////////////////////////////

// The one and only CUsb_matlabApp object

CUsb_matlabApp theApp;

#i nclude "math.h"

#i nclude "mex.h"

#i nclude "EasyUSB.h"

#define WRITE  1

#define READ   0

unsigned char i;

double   *pw;

 double *pr;

 unsigned char data[5];

 unsigned char value[10];

void send(unsigned char  *Buf);

void Receive(unsigned char *Buff);

void mexFunction(int nlhs, mxArray *plhs[], int nrhs,const mxArray *prhs[])

{

 mexPrintf("友情提示:本程序应输入变量为六个,第一位为0表示ADC,为1表示DAc。第二位为功能选择,第三位为通道选择,第四、第五位为数值位\n");

 if(nrhs !=6)

  mexErrMsgTxt("输入变量个数应为6\n");

 /**************

 ****exsample

 

 if(!mxIsNumeric(prhs[0]))

  mexErrMsgTxt("第1个输入变量应为double类型\n");

 if(!mxInNumeric(prhs[1]))

  mexErrMsgTxt("第2个输入变量应为double类型\n");

 xlen = mxGetN(prhs[0]);

 if(xlen<1 || xlen>MAXLEN)

  mexErrMsgTxt("第2个输入变量的长度为1到128\n");

 if(xlen != ylen)

  mexErrMsgTxt("两个输入变更的长度应该相等\n");

 */

 

 pw =mxGetPr(prhs[1]);

 //pr=mxGetPr(plhs[0]);

//unsigned char data=(unsigned char)mxGetScalar(prhs[1]);

 //double * data = mxGetChars(prhs[1]);

 //unsigned char * data = (unsigned char *)mxGetData(prhs[1]);

 //unsigned char * data = (unsigned char *)mxGetChars(prhs[1]);

 for(int i=0;i<5;i++)

    {

  //mexPrintf("%d \n" ,pw[i]);

  data[i]=(unsigned char )mxGetScalar(prhs[i+1]);

  //mexPrintf("%d \n" ,data[i]);

 }

 if((unsigned char)mxGetScalar(prhs[0]) == WRITE)

 {

  send( data );

 }

 else if((unsigned char)mxGetScalar(prhs[0])==READ)

 { 

  send(data);

  Receive(value);

  int tmp=value[0];

  int result=(tmp<<8) | value[1];

  mexPrintf("ADC的结果为:%d\n",result);

  for(unsigned char aa=0;aa<2;aa++)

   mexPrintf("使用八进制表示为:%d(第一位为高字节位)\n",*(value+aa));

 }

 

}

//参数定义:EndP为端点号的选择写的时候只能选用1 和 3

//     EndP=0为端点1的读选通端点号,EndP=2为端点2的读选通端点号

void send(unsigned char  *Buf)

{

  

 unsigned char  ret = WriteData(3,Buf,5,1000);

 mexPrintf("发送的数据为:\n");

 for(i=0;i<5;i++)

    {

  mexPrintf("%d \n" ,*(Buf+i));

 }

 if (ret != 5)       //发送10个字节

 {

  //AfxMessageBox("发送数据错误!\n");

  mexPrintf("发送数据错误!\n");

  return ;

 }

}

//读数据请求的函数

//参数: EndP:端点号的选定 0  或 2

//       lend: 读取数据的长度

//       Buff:数据缓存地址

//说明:收到的数据在Matlab中显示读取结果

void Receive(unsigned char *Buff)

{

 

 unsigned char ret = ReadData(2,Buff,10,1000);  //接收lend个字节

    // mexPrintf("\n   接收数:%d \n", ret);

 if (ret != 10)

 {

  //AfxMessageBox("接收数据错误!\n");

     mexPrintf("接收数据错误!\n");

  return ;

 }

  //  mexPrintf("收到的数据:\n");

 //for (int i=0; i < lend; i++)

 //{

 // mexPrintf(" %d ", *(Buff+i));

 //}

 //mexPrintf("\n");

 

}

  评论这张
 
阅读(130)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018