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

鑫淼梦园的博客

圆你的梦想 从这里开始

 
 
 

日志

 
 

Delphi与MATLAB的数据接口方案探讨  

2012-10-14 13:01:01|  分类: delphi xe2 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

方案四 利用动态链接库技术进行数据交流 
一、基本思路
Matlab本身并没有提供与Delphi的应用程序接口,但是提供了基于win32平台的VC++应用程序接口,包括Matlab引擎(engine),C/C++函数库。可以利用Matlab与VC++的接口函数,通过matlab引擎进行指令处理和数据传递,编写出C++语言的动态连接库,作为Matlab与Delphi的接口,然后在Delphi中进行C++动态库函数的调用。Matlab引擎的C语言调用函数见表1。
表1:Matlab引擎的C语言调用函数
函数名 功  能
EngOpen 打开Matlab引擎
EngEvalString 在Matlab引擎中执行一条命令
EngPutArray 将数据放入Matlab引擎
EngGetArray 从Matlab引擎中取出数据
EngClose 关闭Matlab引擎
在使用表1所示的Matlab引擎函数时,要用到Matlab数组(mxArray),Matlab引擎利用这个数据类型来进行各种数据处理工作。Matlab中的各种变量,包括标量、矢量、矩阵、字符串等都是用这种Matlab数组来进行存储的。Matlab提供了C语言下的Matlab数组(mxArray)的格式,定义了它的数据结构。Delphi下没有对应的Matlab数组,但利用动态连接库可以巧妙地解决这个问题。
二、动态连接库的设计
在我们设计的软件中,要将Delphi中的数据送入Matlab进行分析,选择合适的处理函数后进行运算,然后将结果送回Delphi。为了实现上述目的,设计了相应的几个函数。这些函数都放在DpLab.dll动态连接库中。DpLab.dll的基本组成如下:
(1)头函数
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "engine.h" //在Matlab\extern\include下,将它拷入当前目录
engine *ep=NULL; //Matlab引擎,全局变量
mxArray *PA=NULL; //Matlab数组指针。可根据需要定义多个mxArray指针变量
(2)打开Matlab引擎函数:
extern"C" declspec(dllexport)int MatOpenEng(far char *cc)
{
if(ep) return 0;//如果已打开则退出
if(!(ep=engOpen(cc))) return -1;
else return 1;
}
如果Matlab安装在本地计算机上,字符串cc中的内容为“{post.content}”,如果系统为客户机/服务器(Client/Server)的工作方式,Matlab安装在主机“host”上,可输入'\host\Matlib'。
(3)关闭Matlab引擎的函数
extern"C" declspec(dllexport)int MatCloseEng(void)
{
if(ep)
{
if(PA) mxDestroyArray(PA);//释放PA
engClose(ep);
ep=NULL;
return1;
}
else return0;
}
(4)执行Matlab命令函数:
extern"C" declspec(dllexport)int MatExec(far char *cc)
{
if(!ep)return0;
engEvalString(ep,cc);//cc中放Matlab命令return 1;
}
(5)根据已知数据创建mxArray变量:
//注:cc:Matlab变量名 num:数据的个数 dd:已知数据
extern"C" declspec(dllexport)int MatCreateDoubleD(char *cc,int num,double dd[])
{
if(!ep) return 0;
if(num<1) return -1;
PA=mxCreatedoubleMatrix(1,num,mxREAL);
mxSetName(PA,fh[Getfh(cc)]);//指定Matlab中变量名,它必须是静态字符串!
memcpy((char *)mxGetPr(PA),(char *)dd,num * sizeof(double));
engPutArray(ep,PA);
return1;
}
(6)获取Matlab数据:
//注:cc:Matlab变量名 num:数据的个数 dd:返回数据
extern"C" declspec(dllexport)int MatGetdoubleData(char *cc,int num,double dd[])
{
mxArray result;
double pData;
int i;
if(!ep)return0;
if(num<1)return-1;
result=engGetArray(ep,fh[Getfh(cc)]);
if(result)
{  
pData=(double )mxGetData(result);  
for(i=0;i<num;i++) dd=pData;  
mxDestroyArray(result);  
return1;
}
return 0;
}
还可以根据需要定义其它一些函数如获取变量名函数intGetfh(charcc[])等等。这些函数写好以后,可以用VC进行编译,将编译好的动态连接库DpLab.dll复制到Windows\system下。
三、各种函数在Delphi中的运用
1、为了在Delphi中使用动态连接库函数,首先要对这些函数作如下声明:
function MatOpenEng(p:PChar):Integer;stdcall;external'DpLab.dll';
function MatCloseEng:Integer;stdcall;external'DpLab.dll';
function MatExec(p:PChar):Integer;stdcall;external'DpLab.dll';
function MatCreateDoubleD(p:Pointer;num:Integer;dd:Array of double):Integer;stdcall;external'DpLab dll';
function MatGetdoubleData(p:pointer;num:Integer;dd:Array of double):Integer;stdcall;external'DpLab dll';
函数声明了以后,就可以方便地使用它们了。
打开Matlab引擎用:MatOpenEng(PChar({post.content}'));
关闭Matlab引擎用:MatCloseEng;
2、下面的程序给出了从Matlab中获取数据的方法,函数MatGetDoubleData通过变量cc指定Matlab中的数据变量名,该变量应是已经定义好的:
procedure TForm1Button2Click(Sender:Tobject);
var dd:Array[0..10] of double;cc:char;i:integer;
begin
cc:='D';//Matlab中的变量名
MatGetDoubleData(@cc,10,dd);
ListBox1.clear;//在一个列表框内显示读出的数据
for i:=0 to 4 do ListBox1.items.add(format('%.2f,[dd]));
end;
  3、下面给出Delphi在Matlab中用sin(r)/r函数画出三维图形的程序,其余情况大家触类旁通吧^_^
procedure TForm1Button3Click(Sender:Tobject);
begin
MatExec(PChar('x=-8: 5:8;'));
MatExec(PChar('y=x',';'));
MatExec(PChar('X=ones(size(y))*x;'));
MatExec(PChar('Y=y*ones(size(x));'));
MatExec(PChar('R=sqrt(X.^2+Y.^2)+eps;'));
MatExec(PChar('Z=sin(R)/R;'));
MatExec(PChar('mesh(Z);'));
end;
四、方案总结
其实思路和上一种方案很像,不同的是是通过调用dll中的matlab应用程序接口指令实现数据传输,本方案所提供的动态连接库实际上是一个示范性的例子,根据实际需要还可以开发出功能更强大的函数,以满足不同应用场合的需要。就是要花费一定时间编写相关的dll咯^_^   本文来自网络摘抄

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

历史上的今天

在LOFTER的更多文章

评论

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

页脚

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