由生成的共享库MATLAB®编译器SDK™包含至少七个功能。有三个生成的函数来管理库初始化和终止,每个函数为每个用于打印的输出和错误消息,以及编译到库中的每个MATLAB文件的两个生成的函数。
要生成本节描述的函数,请先复制Sierpinski.m.
和三角形
要创建C共享库,triangle_legacy.cpp
来创建一个c++MWARRAY.
API共享库triangle_generic.cpp.
创建一个C++ Matlab数据API共享库到你的目录中。这些文件可以在中找到
.matlabroot.
\ extern \ examplex \ compilersdk \ c_cpp \三角形
如上所述创建共享库从命令行创建C / C ++共享库. 在…上ce your shared library is created, execute the followingMBUILD.
与您的开发平台对应的命令。这个命令使用您的C/ c++编译器来编译代码,并将驱动程序代码链接到MATLAB生成的C/ c++共享库。
对于C应用程序,使用mbuild triangle.c libmatrix.lib.
.
对于C ++MWARRAY.
API应用程序中,使用mbuild triangle_legacy.cpp libtriangle.lib
对于C ++ MATLAB数据API应用程序,使用mbuild矩阵_mda.cpp libtriangle.lib
请注意
的.lib.
扩展是适用于Windows®. 在…上苹果,文件扩展名为迪利布先生
,在UNIX上®这是所以
.
此命令假定C / C ++共享库,驱动程序代码和相应的标题文件位于当前工作文件夹中。
这些命令创建一个名为的主要程序三角形
和一个名为的共享库libtriangle.
.库导出一个使用简单迭代算法的单个函数(包含在Sierpinski.m.
)生成称为Sierpinski三角形的分形。主要方案三角形
,triangle_legacy.cpp
, 和triangle_generic.cpp.
可以选择采用单个数字参数,如果存在,则指定用于生成分形的点数。例如,三角形8000
生成8,000点的图表。
在这个例子中,Matlab Compiler SDK.将所有生成的函数放入生成的文件中libtriangle.c
要么libtriangle.cpp.
.
所有调用Matlab Compiler SDK.生成的共享库具有大致相同的结构:
声明变量并处理/验证输入参数。
呼叫Mclinitializapplication
并测试成功。此功能设置全局Matlab运行时状态和使能的构建Matlab运行时实例。
致电,一次为每个库,
,创造Matlab运行时库所需的实例。
调用库中的函数,并处理结果(这是程序的主体。)
致电,一次为每个库,
,摧毁相关的Matlab运行时.
呼叫mclTerminateApplication
与全球相关的免费资源Matlab运行时状态。
清理变量,关闭文件等,然后退出。
要在实际示例中查看这些步骤,请查看本示例中的主程序,三角形
.
库初始化和终止功能分别创建和销毁Matlab运行时共享库所需的实例。您必须在调用共享库中的任何其他函数之前调用初始化函数,并且您应该在完成拨打中拨打共享库(或您风险泄漏内存)后调用终止功能。
有两种形式的初始化函数和一种类型的终止函数。两个初始化函数中较简单的一个不接受参数;这很可能是应用程序将调用的版本。在本例中,调用这种形式的初始化函数libtriangleinitialize.
.
BOOL LibtriangleInitialize(无效)
此功能创建一个Matlab运行时实例使用默认的打印和错误处理程序以及编译过程中生成的其他信息。
但是,如果希望对打印输出和错误消息的处理方式有更多的控制,可以调用函数的第二种形式,它包含两个参数。
bool libtriangleInitializeWithHandlers(mclOutputHandlerFcn error_handler, mclOutputHandlerFcn print_handler)
通过调用此函数,您可以提供由调用的打印和错误处理例程的自己版本Matlab运行时.这些例程中的每一个都具有相同的签名(有关完整的详细信息,请参阅打印和错误处理函数)。通过覆盖默认值,您可以控制如何显示输出,例如,它是否进入日志文件。
请注意
在调用任何形式的库初始化例程之前,必须先呼叫Mclinitializapplication
建立全球Matlab运行时状态。看到调用C共享库了解更多信息。
关于微软®Windows平台上,Matlab Compiler SDK.生成一个附加的初始化函数,即标准的Microsoft DLL初始化函数德尔曼
.
BOOL WINAPI DLLMAIN(HINSTANCE HINSTANCE,DWORD DWRERON,VOID * PV)
生成的德尔曼
执行一个非常重要的服务;它找到了共享库存储在磁盘上的目录。此信息用于查找可部署的存档,而无需该应用程序不会运行。如果修改生成的德尔曼
(不推荐),请确保保留其这部分功能。
库终止很简单。
void libtrianglearerminate(空白)
在调用之前调用此函数(每个库一次)mclTerminateApplication
.
默认情况下,Matlab Compiler SDK.生成的应用程序和共享库将打印输出发送到标准输出,将错误消息发送到标准错误。Matlab Compiler SDK.生成默认的打印处理程序和实现此策略的默认错误处理程序。如果您想更改此行为,则必须编写自己的错误和打印处理程序并将其传递给适当的生成初始化功能。
您可以替换这两个功能中的两者或两者。的Matlab运行时通过打印处理程序发送所有常规输出,并通过错误处理程序发送所有错误输出。因此,如果您重新定义其中一个函数,则Matlab运行时将使用您的函数版本来处理属于它调用该处理程序的类的所有输出。
默认打印处理程序采用以下表单。
静态int-mclDefaultPrintHandler(常量字符*s)
实现简单;它接受一个字符串,在标准输出上打印,并返回打印的字符数。如果重写或替换此函数,则版本还必须采用字符串并返回“已处理”的字符数Matlab运行时当执行MATLAB文件为打印输出请求时调用打印处理程序,例如,通过MATLAB函数disp
.打印处理程序不会用回车或换行来终止输出。
默认错误处理程序的形式与打印处理程序相同。
static int mclDefaultErrorHandler(const char *s)
然而,打印处理程序的默认实现略有不同。它将输出发送到标准错误输出流,但如果字符串没有以回车符结束,则错误处理程序添加一个回车符。如果将默认的错误处理程序替换为您自己的错误处理程序,您也应该执行此检查,或者由Matlab运行时不会正确格式化。
小心
错误处理程序,尽管它的名称是错误处理程序,但它并不处理实际的错误,而是在捕获和处理错误之后产生的消息Matlab运行时.控件的错误处理行为不能使用此函数Matlab运行时- 使用尝试
和抓住
在MATLAB文件中,如果你想控制如何Matlab Compiler SDK.生成的应用程序响应错误条件。
请注意
如果您提供了任意的C++实现McDefaultPrintHandler.
要么mclDefaultErrorHandler
,必须声明函数extern“c”
.例如:
外部“C”int myPrintHandler(const char*s);
中指定的每个MATLAB文件Matlab Compiler SDK.命令行,产品生成两个函数,对mlx
功能和mlf
功能。每个生成的函数执行相同的操作(调用MATLAB文件函数)。这两个函数具有不同的名称,并提供不同的接口。每个函数的名称基于MATLAB文件中第一个函数的名称(Sierpinski.
,在本例中);每个函数都以不同的三个字母前缀开头。
请注意
对于C共享库,Matlab Compiler SDK.生成mlx
和mlf
本节提供的功能。对于c++共享库,产品生成mlx
函数的处理方法与C共享库相同。然而,该产品产生了一个修改mlf
功能与这些差异:
的mlf
在删除函数名称以保持与R13的兼容性之前。
函数的参数是MWARRAY.
而不是mxarray.
.
以前缀开头的函数mlx
采用与MATLAB MEX函数相同的参数类型和数量(有关MEX函数的更多详细信息,请参阅外部接口文档。)第一个参数,nlhs.
,是输出参数的数量,以及第二个参数,plhs
,是指向数组的指针,函数将用请求的返回值填充该数组("lhs
“在这些参数名称中对于”左侧“而言 - Matlab表达式中的输出变量是分配运算符的左侧的输出变量。)第三和第四个参数是输入和数组的数量包含输入变量。
void mlxsierpinski(int nlhs,mxarray * plhs [],int nrhs,mxarray * prhs [])
生成的函数的第二个以前缀开头mlf
.这个函数期望它的输入和输出参数作为单独的变量传入,而不是打包到数组中。如果函数能够产生一个或多个输出,则第一个参数是调用者请求的输出数量。
void mlfSierpinski(int nargout, mxArray** x, mxArray** y, mxArray* iterations, mxArray* draw)
在这两种情况下,生成的函数为其返回值分配内存。如果不删除此内存(通过mxdestroyarray.
)当您完成输出变量时,您的程序将泄漏内存。
您的程序可能会呼叫这些功能的任何方便,因为它们都以相同的方式调用Matlab文件函数。大多数程序都会拨打电话mlf
避免管理所需额外数阵的功能的形式mlx
的形式。中的示例程序三角形
调用MLFSIERPINSKI.
.
mlfsierpinski(2,&x,&y,迭代,绘图);
在这个调用中,调用者请求两个输出参数,x
和y
,并提供两个输入,迭代
和画
.
如果你传入的输出变量mlf
函数不是NULL,则mlf
功能将尝试释放它们mxdestroyarray.
.这意味着您可以在连续调用中重用输出变量mlf
函数,而不必担心内存泄漏。这也意味着你必须通过其中之一无效的
或者为所有输出变量创建有效的MATLAB数组,否则您的程序将失败,因为内存管理器无法区分未初始化(无效)数组指针和有效数组。它将尝试释放一个非空指针——释放一个无效指针通常会导致分段错误或类似的致命错误。
如果您的Matlab功能界面使用varargin.
要么varargout.
,则必须将它们作为单元格数组传递。例如,如果你有N
varargin.
s,您需要创建一个单元格数组1-by-n
.同样的,varargout.
s作为一个单元阵列返回。的长度varargout.
等于函数调用中指定的返回值的数量减去实际变量的数量传递。与MATLAB软件一样,单元格数组表示瓦拉特
必须是最后一个返回变量(第一输入变量之前的变量)和表示的单元格数组varargin.
s必须是函数调用的最后一个正式参数。
有关创建单元格阵列的信息,请参阅外部接口文档中的C MEX功能界面。
例如,考虑这个Matlab文件接口:
[a, b, varargout] = myfun (x, y, z,变长度输入宗量)
对应的C接口是
void mlfmyfun(Int numofreetvars,mxarray ** a,mxarray ** b,mxarray ** varargout,mxarray * x,mxarray * y,mxarray * z,mxarray * varargin)
在本例中,中的元素数varargout.
是(numofreetvars - 2)
哪里2
代表两个变量,一个
和b
,被返回。这两个varargin.
和varargout.
是单行,多列单元格阵列。
小心
C++共享库接口不支持金宝appvarargin.
具有零(0)个输入参数。使用空的MWARRAY.
导致打包库接收空数组,其中输入参数个数= 1
. C共享库接口允许您调用mlfFOO(空)
(打包的MATLAB代码将其解释为输入参数个数= 0
). 但是,foo((mwarray)null)
使用c++共享库接口会使打包的MATLAB代码看到一个空数组作为第一个输入并解释输入参数个数= 1
.
例如,将一些MATLAB代码包装为C ++共享库使用varargin.
作为MATLAB函数的输入参数列表。让MATLAB代码显示变量函数输入变量数
. 使用函数调用库
它不会打包,产生这个错误消息:喷火
()
……”喷火':函数不需要0个参数
mwArray垃圾;喷火(垃圾);
喷火((mwarray)null);
输入参数个数= 1
.在MATLAB中,喷火
()
是输入参数个数= 0
和Foo([])
是输入参数个数= 1
.
C ++接口MATLAB使用varargin和varargout的函数。C ++mlx
即使功能使用,MATLAB函数的接口也不会更改varargin.
要么varargout.
.然而,如果使用MATLAB函数,c++函数接口(第二组函数)会发生变化varargin.
要么varargout.
.
例如,查看使用的各种MATLAB函数签名的生成代码varargin.
要么varargout.
.
请注意
为了简单起见,下面的例子中只显示了生成的C++函数签名的相关部分。
功能varargout = foo(i1,i2,varargin)
使用共享库时,可以调用函数从Matlab运行时状态。有关详细信息,请参见为共享库设置和检索MATLAB运行时数据.