在MATLAB环境下访问外部函数的共享库文件Word文档格式.docx

上传人:b****8 文档编号:22874492 上传时间:2023-02-05 格式:DOCX 页数:20 大小:25.60KB
下载 相关 举报
在MATLAB环境下访问外部函数的共享库文件Word文档格式.docx_第1页
第1页 / 共20页
在MATLAB环境下访问外部函数的共享库文件Word文档格式.docx_第2页
第2页 / 共20页
在MATLAB环境下访问外部函数的共享库文件Word文档格式.docx_第3页
第3页 / 共20页
在MATLAB环境下访问外部函数的共享库文件Word文档格式.docx_第4页
第4页 / 共20页
在MATLAB环境下访问外部函数的共享库文件Word文档格式.docx_第5页
第5页 / 共20页
点击查看更多>>
下载资源
资源描述

在MATLAB环境下访问外部函数的共享库文件Word文档格式.docx

《在MATLAB环境下访问外部函数的共享库文件Word文档格式.docx》由会员分享,可在线阅读,更多相关《在MATLAB环境下访问外部函数的共享库文件Word文档格式.docx(20页珍藏版)》请在冰豆网上搜索。

在MATLAB环境下访问外部函数的共享库文件Word文档格式.docx

uint8mxIsInf(double)

值得注意的是,这两个函数返回值的类型均是MATLAB的数据类型,虽然函数是利用C语言编写的。

调用库函数

一旦库函数被加载到了内存空间,只要指定库名、函数名和变量就可以使用calllib函数调用库中的任何函数了。

语法格式:

calllib(‘libname’,’funcname’,arg1,…,argn)

下列语句显示如何操作:

hfile=['

C:

\MATLAB7\extern\include\matrix.h'

];

loadlibrary(‘libmx’,hfile);

y=rand(4,7,2);

%producea3Darray,thereare56elementsinit

calllib(‘libmx’,’mxGetNumberOfElements’,y)

ans=

56

Calllib(‘libmx’,’mxGetClassID’,y)

mxDouble_CLASS

传递变量

当调用外部库里的函数时,该为函数提供哪种类型的变量呢?

MATLAB的extern\examples\shrlib\shrlibsample库里对每一种特殊的变量类型都作出了说明。

但我们首先必须把该库文件的路径添加到MATLAB的搜索路径中来,或者使该库文件所在的目录成为当前目录,两种做法的命令如下。

addpath(‘C:

\MATLAB7\extern\examples\shrlib’)

cd(‘C:

下面的例子就是加载该库并显示了其中的一些函数。

loadlibraryshrlibsampleshrlibsample.h

libfunctionsshrlibsample–full

执行上述两行后,返回:

Functionsinlibraryshrlibsample:

[double,doublePtr]addDoubleRef(double,doublePtr,double)

doubleaddMixedTypes(int16,int32,double)

[double,c_structPtr]addStructByRef(c_structPtr)

doubleaddStructFields(c_struct)

c_structPtrPtrallocateStruct(c_structPtrPtr)

voidPtrdeallocateStruct(voidPtr)

doublePtrmultDoubleArray(doublePtr,int32)

[lib.pointer,doublePtr]multDoubleRef(doublePtr)

int16PtrmultiplyShort(int16Ptr,int32)

stringreadEnum(Enum1)

[string,string]stringToUpper(string)

这里所有的函数都是用C语言编写的。

一些通用的规则

在函数的输入输出变量问题上,以下几点应注意:

1.许多变量类型,象int32、double与C语言的数据类型非常相象。

这些变量只需要传递MATLAB型的数据就可以了。

2.而有些C语言的变量类型,象**double、还有预定义型与标准MATLAB数据类型是完全不同的。

这种情况下,有两种选择,要么给外部函数的入参传递标准的MATLAB数据类型,让MATLAB程序自动转化,要么先使用MATLAB提供的转化函数,如libstruct、libpointer自己转化。

关于转化,可以参考DataConversion。

3.C语言通常可以按形参传递变量,但MATLAB不支持这种做法,不过可以创造MATLABPtr或PtrPtr型的变量,去兼容C语言的形参。

4.C语言通常还可以通过形参来返回输入变量的值,而MATLAB需要额外的变量来获得返回值。

传递变量的通用规则

1.库函数传递形参时,标量不必非得声明。

2.如果库函数使用单下标来引用二维矩阵元素时,请记住,C语言是逐行处理矩阵元素,而MATLAB是按列优先处理的。

因此迎合C语言的习惯,可以在给MATLAB函数传递变量之前把矩阵进行转置,从函数返回后再转置回来就行了。

3.由上可知,当传递的矩阵超过二维时,MATLAB会改变矩阵的行列结构,为了确保矩阵的结构不被破坏,可以事先记录矩阵的结构,在调用结束后利用reshape函数还原即可。

例如:

vs=size(vin);

%supposethedimentionofvectorvinis2-by-5-by2

vout=calllib(‘shrlibsample’,’multDoubleArray’,vin,20);

%dimentionhavebeenaltered

210

vout=reshape(vout,vs);

%Restorethearrayto2-by-5-by-2

size(vout)

252

4.当支持可选参数时,可用一空矩阵来传递一个NULL型参数。

这是在变量为Ptr或PtrPtr型时唯一的选择。

传参

外部库的许多函数是传递形参的,为了能与这些函数交互,MATLAB通常传递一个叫“指针对象”的变量,不过别把它与传参混同了。

数据转化

在多数情况下,传递给外部库函数或从外部库函数返回的数据类型自动被MATLAB转化,然而,或许你偶尔也希望有些时侯能手动转化:

1.当需要传递相同的数据给一系列库函数时,可能手动转化要比让MATLAB自动转化更为明智,更能节省时间。

2.当传递大结构的数据时,手动转化数据使之匹配C结构而不是直接采用通用的MATLAB型数据的做法,比直接使用libstruct函数把C结构型的数据转换成MATLAB型数据更能节省内存。

3.当外部函数使用超过一层引用(例如,指向指针的指针变量double**)时,用libpointer函数构造一个参数,比直接让MATLAB自动转化数据要好。

原始类型

共享库接口支持所有标准C数据类型。

下表显示了C与MATLAB等价的数据类型。

C类型(32位机器)

等价MATLAB类型

char,byte

int8

unsignedchar,byte

uint8

short

int16

unsignedshort

uint16

int,long

int32

unsignedint,unsignedlong

uint32

float

single

double

char*

string(1-by-nchararray)

下表显示的lib.pointer类中的数据类型,非MATLAB标准类型

C数据类型(32位机器)

扩展MATLAB数据类型

integerpointertypes(int*)

(u)int(size)Ptr

float*

singlePtr

double*

doublePtr

mxArray*

MATLABarray

void*

voidPtr

type**

sameastypePtrwithanaddedPtr(e.g.,double**isdoublePtrPtr)

MATLAB可以自动把转化数据为外部库函数所需要的任何原型数据,这就意味着可以传递一个双精度型数据给一个8位整数型变量。

下述C函数接受短整型、整型和双精度型数据:

doubleaddMixedTypes(shortx,inty,doublez)

{

return(x+y+z);

}

你可以极其简单地在MATLAB中只传递给该函数以双精度变量,MATLAB自动判断每个变量接受何种类型的变量,并作近似转化。

calllib(‘shrlibsample’,’addMixedTypes’,127,33000,pi)

3.3130e+004

转化参数

当外部函数原型定义一个形参时,MATLAB能自动地把一个按值传递的变量转化为形参。

因此,当给一个双精度指针变量赋一双精度变量时,MATLAB会自动地把该双精度变量转化为双精度形参。

addDoubleRef是一个接受双精度指针型形参的函数:

doubleaddDoubleRef(doublex,bouble*y,doublez)

return(x+*y+z);

用三个双精度变量调用该函数,MATLAB自动处理数据转化:

calllib(‘shrlibsample’,‘addDoubleRef’,1.78,5.42,13.3)

20.5000

字符串

当变量需要字符型指针数据时,你可以传递一个MATLAB型字符串(矩阵)。

下述C函数接受一个字符指针型数据:

char*stringToUpper(char*input)

{

char*p=input;

if(p!

=NULL)

while(*p!

=0)

*p++=toupper(*p);

returninput;

libfunctions显示,你可以用一个MATLAB字符串作为输入。

[string,string]stringToUpper(string)

定义一个MATLAB字符矩阵str,把它传递给变量。

str=’ThiswasaMixedCasestring’;

%MATLAB中字符串以“’”号对表示

calllib(‘shrlibsample’,‘stringToUpper’,str)

THISWASAMIXEDSTRING

注意:

虽然MATLAB传递给变量的很象字符型的形参,但它并不真正的参数类型。

因为它并不包括MATLAB字符矩阵str的地址。

因此当函数执行完毕时,字符串的值并未改变。

枚举型

如果变量被定义为C中的枚举型,你可以传递枚举型或一个与枚举值等价的整数。

shrlibsample库中的readEnum函数返回与传入变量相应的枚举型。

下述为Enum1的定义和C语言函数readEnum:

enumEnum1{en1=1,en2,en4=4}TEnum1;

char*readEnum(TEnum1val)

switch(val){

case1:

return“youchoseen1”;

case2:

return“youchoseen2”;

case4:

return“youchoseen4”;

default:

return“enumnotdefined”;

}

MATLAB,你可以用一个枚举型字符或等价的整数来表示枚举型数据。

上述中定义的枚举型数据TEnum1中,en4与4等价:

calllib(‘shrlibsample’,‘readEnum’,‘en4’)

youchoseen4

calllib(‘shrlibsampel’,‘readEnum’,4)

结构体型

当库函数接受结构体型变量时,你需要给它传递与在结构体定义时拥有相同域名的结构体变量。

为了确定结构体变量的域和类型,你可以:

1.查询库文档

2.在加载到MATLAB的库的头文件中寻找结构体的定义。

你也可以在MATLAB中采用下述步骤来确定外部函数定义过的结构体的域名。

1.利用libfunctionsview函数来显示正在使用的库函数的信息,它包含了每一个函数所做用的结构体数据的名字。

当键入libfunctionsviewshrlibsample命令时,MATLAB就会在新窗口中显示库函数的信息。

如:

doubleaddStructFields(c_struct)

2.利用libstruct函数获取结构体定义模型。

如s=libstruct(‘c_struct’);

3.继而利用get函数返回结构体数据的域名。

如get(s)

p1:

p2:

p3:

4.利用calllib函数初始化所需要传递给库函数的域值。

如s.p1=478;

s.p2=-299;

s.p3=1000;

calllib(‘shrlibsample’,‘addStructFields’,s)

当你利用calllib函数创建或初始化结构体数据时,不必去匹配结构体的数据域,MATLAB会自动转化数据类型。

指定结构体域名

下面是在为外部库函数传递结构体数据时一般的做法:

1.结构体数据可能只包含了定义中很少的一部分域,MATLAB会把其余的域初始化为0.

2.你所使用的任何结构体的域名须与定义中的域名一致。

3.结构体中不能包含库函数中未定义过的域名。

传递MATLAB结构体

与其他的数据类型一样,当外部函数接受结构体变量数据类型时,就可以传递一个MATLAB型结构体数据给它。

结构体的域名必须与库函数定义中的域名一致,而数值类型则可以不同,由MATLAB自动转换完成。

如shrlibsample共享库中定义了这样的C结构和函数:

structc_struct{

doublep1;

shortp2;

longp3;

};

doubleaddStructField(structc_structst)

doublet=st.p1+st.p2+st.p3;

returnt;

}

下面的代码完成向addStructField函数传递一个结构体变量sm,包含三个双精度数据,即传递的数值类型与C定义中的不一样,但域外必须相同,否则传递不进去:

sm.p1=476;

sm.p2=-299;

sm.p3=1000;

calllib(‘shrlibsample’,‘addStructFields’,sm)

1177

传递结构体对象

当为外部函数传递结构体变量时,MATLAB为了确保传递成功,要求域名必须与库函数定义中的一致,而对数值类型则不加强求,由MATLAB自动转换成库函数中对应域的数值类型,并且把空域的值均初始化为零。

当结构体数据较小时,这种做法很有效。

然而,当重复传递一个或多个大的结构体数据时,手动转化是更明智的选择,不仅可以节省时间,还可以节省内存和空间。

使用libstruct函数

s=libstruct(‘structtype’,mlstruct)

返回值s叫做libstruct对象。

虽然它实际上是MATLAB的一个对象,但它更象是一个结构体数据。

这个新的所谓“结构体”的域名得自于外部库函数中结构体的域名。

例如,把MATLAB结构体sm转换成libstruct对象sc:

sc=libstruct(‘c_struct’,sm);

sm的原始结构中域值为三个双精度型,而libstruct函数转换后的sc对象的域名则与c_struct结构体一致,分别为double、short和long型。

创建空libstruct对象

s=libstruct(‘structtype’)这种调用格式可以生成域名完整,域值为0的空libstruct对象。

使用结构体作为对象

libstruct转换后的结构体实际上是lib.c_struct类中的一个对象实例,这一点可以通过whos命令的输出来验证:

whossc

NameSizeBytesClass

sc1-by-1lib.c_struct

Grandtotalis1elementusing0bytes

域已经被当成了lib.c_struct类的属性来处理了。

你可以利用基于对象的函数set和get来读写:

sc=libstruct(‘c_struct’);

set(sc,‘p1’,100,‘p2’,150,‘p3’,200);

%对象读写须用get、set

get(sc)

100

150

200

但是你也可以象处理结构体数据那样简单地对sc进行读写:

sc.p1=23;

%而结构体的域可以直接赋值

sc.p1

23

创建形参

你可以为外部函数按值传递大多数的变量,即使函数原型要求形参传递,然而有时你会发现这与直接给C传递形参一样揍效。

使用库指针函数

用函数libpointer构造一个形参的语法如下:

p=libpointer(‘type’,‘value’)

例如要创建一个指向int16数据类型的指针pv,就得先指定指针的类型,并以Ptr作后缀:

v=int16(485);

pv=libpointer(‘int16Prt’,v);

返回值pv实际就是MATLAB中lib.pointer类的一个实例。

lib.pointer有属性值和数据类型。

你可以用get或set函数来读或写这些属性。

get(pv)

value:

485

DataType:

’int16Ptr’

lib.pointer类还有另外两种方法setdatatype和reshape。

methods(pv)

methodsforclasslib.pointer:

setdatatypereshape

为原始类型创建形参

如何去创建和传递指针给双精度型,又如何输出数据这里有一个简单的例子可以说明。

函数multDoubleRef接受一个双精度形参同时返回双精度型。

double*multDoubleRef(double*x)

*x*=5;

returnx;

输入数据x来创建一个形参xp:

x=15;

xp=libpointer(‘doublePtr’,x);

get(xp)

15

Datatype:

’doublePtr’

现在可以调用函数来检验结果:

calllib(‘shrlibsample’,‘multDoubleRef’,xp);

get(xp,‘value’)

75

xp虽然是作为x的形参而创建的,但它并非真的象C语言的指针,因为xp中并不包含x的地址,因此,当函数执行时,函数修改xp的属性值,但它并不修改x的值。

获得函数的返回值

在上述最后一例子中,从MATLAB调用的函数返回值可以通过检查修改了的输入形参来获得,但这个函数也可以通过输出变量来获得。

这个函数的MATLAB原型表明(利用libfunctionsshrlibsample–full查看原型),它返回了两个输出变量,一为lib.pointer类的对象,另一为dlublePtr输入变量的属性值:

[lib.pointer,doublePtr]multDoubleRef(doublePtr)

再次运行这个例程,但这次检查返回值

x=15;

xp=libpointer(‘doublePtr’,x);

[xobj,xval]=calllib(‘shrlibsample’,‘multDoubleRef’,xp)

xobj=

lib.pointer

xval=

创建结构体形参

与创建原始类型的形参相比,创建结构体的形参并非难事。

下述函数只接受C语言形式的结构体形参,它的返回值是所有结构体域值之和,同时也修改了输入参量。

doubleaddStructByRef(structc_struct*st)

doublet=st->

p1+st->

p2+st->

p3;

st->

p1=5.5;

p2=1234;

p3=12345678;

(1)传递结构体本身

虽然这个函数期望获得一个结构体的输入参量。

下列给形参传递了一个MATLAB的结构体sm,返回值是正确的,因为sm不是按址传递,所以sm的域值并未被函数修改。

x=calllib(‘sh

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 医学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1