您可以最大限度地利用在MATLAB中开发、测试和验证的算法®通过与未安装MATLAB的其他人共享该算法。为了避免用另一种语言重新编码该算法所带来的开发和测试成本,有两种方法可用:使用MATLAB编译器™ SDK或使用MATLAB编码器™.
MATLAB编译器SDK加密您的算法并将其打包到C/C++共享库中,Microsoft®Python。net程序集,®软件包和Java®类。使用这些组件构建的应用程序在MATLAB运行时上运行,该运行时提供了对MATLAB语言、图形和工具箱的访问,而不需要MATLAB接口。MATLAB Runtime可以安装在任何能够运行MATLAB的目标平台上,比如运行Windows、MacOS或Linux的桌面或服务器平台。
如果在目标平台上安装MATLAB运行时是不可能的,考虑使用MATLAB编码器从MATLAB算法的数值计算部分生成C或C++代码。生成的代码可以用作更大系统的组件。这种方法适用于Android和iOS等智能手机平台。
本文介绍了使用MATLAB Coder在C/ c++、. net或Java环境中部署MATLAB应用程序的工作流,而不需要安装MATLAB Runtime。使用卡尔曼滤波器的代码说明了工作流程。
本示例中使用的代码可用于下载.
C/C++、.NET和Java目标平台的工作流
部署到C/ c++、。net或Java目标平台的起点是使用MATLAB Coder从MATLAB代码生成C代码。下一步是有针对性的,具体如下:
MATLAB中卡尔曼滤波函数的原型为:
函数y = kalmanfilter (z)%%MATLAB代码
部署。净
要让应用程序在。net平台上运行,请遵循以下五个步骤(图1):
- 运行MATLAB Coder从MATLAB代码生成C代码和DLL。
您可以创建MATLAB编码器项目或运行命令行函数codegen
.这两种方法都允许指定输出目录和生成的dll的名称—这是一个很好的实践,因为它避免了将MATLAB当前文件夹与生成的文件混在一起。
对于卡尔曼滤波器,生成C代码的MATLAB命令为:
codegen–o MATLAB_CODER_DLL–d..\autogen_matlabcoder kalmanfilter.m-args{zeros(2,1)}
- 打开由MATLAB Coder生成的头文件*.h,查看由MATLAB函数生成的C函数接口。
在我们的例子中,MATLAB卡尔曼滤波器将被转换成一个C函数,其原型是:
外面的空白Kalmanfilter(const双z [2],双重的y [2]);/*C代码*/
我们为双参数生成卡尔曼滤波器,因为双参数是MATLAB的默认类型。(注意,MATLAB Coder允许您更改生成代码的数据类型,而无需更改您的MATLAB代码。)
- 检查函数参数的C数据类型,并将它们转换为。net数据类型。
这一步很重要,因为您必须用。net语言编写函数声明。有关更多信息,请参见平台调用数据类型.
表1显示了等价的C和。net类型。
C类型 | net类型 | 描述 |
---|---|---|
空虚* | 系统。IntPtr | 32位Windows操作系统上的32位 64位的Windows操作系统 |
无符号字符 | 系统。字节 | 8位 |
短的 | 系统。Int16 | 16位 |
无符号短 | 系统。UInt16 | 16位 |
int | 系统。Int32 | 32位 |
无符号整型 | 系统。UInt32 | 32位 |
长 | 系统。Int32 | 32位 |
无符号长 | 系统。UInt32 | 32位 |
烧焦 | 系统。字符 | 用ANSI装饰 |
wchar_t | 系统。字符 | 用Unicode装饰 |
char * | System.String或System.Text.StringBuilder | 用ANSI装饰 |
donst char * | System.String或System.Text.StringBuilder | 用ANSI装饰 |
wchar\t* | System.String或System.Text.StringBuilder | 用Unicode装饰 |
康斯特沃克哈特酒店* | System.String或System.Text.StringBuilder | 用Unicode装饰 |
浮动 | 系统。单 | 32位 |
双重的 | 系统。双 | 64位 |
表1。等价于C和。net数据类型。
该表表明“双”C类型将简单地翻译成一个系统。双
net类型。这意味着C函数原型是这样的:
无效Kalmanfilter(const双z [2],双重的y [2]);/*C代码*/
可以翻译成以下.NET C#函数原型:
无效kalmanfilter(Double[] a, Double[] b);/* c#代码*/
请确保将.NET或Java类型与C类型正确匹配。不匹配不会在编译和运行时引发错误,但数值无效。
- 编写. net代码来声明和调用导入的函数。
在我们的示例中,我们编写了以下Visual Basic .NET代码:
Visual Basic.NET代码导入System.Runtime.InteropServices模块Module1 < DllImport (“MATLAB_CODER_DLL.dll”,CallingConvention:=CallingConvention.Cdecl)>公共子Kalmanfilter(按值传递一()作为双,按值传递b ()作为双)终止子子Main ()昏暗的正义与发展党作为双() ak = {1,2}昏暗的汉堡王作为双() bk = {0,0}终止子终端模块
此外,我们用c#编写了以下代码。
/* c#代码*/使用System.Runtime.InteropServices;类程序{[DllImport (“MATLAB_CODER_DLL.dll”,CallingConvention=CallingConvention.Cdecl)]公共静态外部无效kalmanfilter(Double[] a, Double[] b);静态的空白主要(一串[] args) {Double[] ak = {1,2};双[]bk =新双[2];kalmanfilter (ak, bk);} }
请注意这两种代码之间的相似性:Visual Basic.NET代码提供了一个包含“main”过程的模块,而C#有一个包含“main”方法的类。这两种代码语言都需要使用InteropServices
函数,其中包含用于P/Invoke技术的方法。
生成.NET代码不需要DLL文件或C头文件。相反,构建将依赖于您自己在“DllImport”语句中对函数的.NET声明。这意味着,如果.NET声明与C声明不兼容,但与.NET调用兼容,则生成.NET代码不会引发错误。该错误仅在运行时出现。
- 运行.NET代码。确保将DLL文件和可执行文件存储在同一文件夹中。
部署到Java平台
要准备应用程序在.Java平台上运行,请遵循以下七个步骤(图2):
- 运行MATLAB编码器从您的MATLAB代码生成C代码。
生成卡尔曼滤波器的C代码的MATLAB命令如下
codegen -o MATLAB_CODER_DLL -d ..\ autogen_matlabcoder kalmanfilter。m参数{0 (2,1)}
当部署到JAVA时,我们使用选项“-c”,而不是DLL。来生成c代码。我们需要编写额外的c代码来获得JAVA的最终DLL。
- 编写包含函数的Java声明的Java代码。
Java声明不仅在语法和数据类型上不同于C声明,而且在参数上也不同。C函数接受数组指针作为输出参数,而Java则返回对象数组。相应地,您必须将您的C原型转换为Java原型。但是,请记住,您的C函数的包装器,而不是C本机函数,将在Java代码中直接调用。
对于卡尔曼过滤器,我们编写以下Java代码,并将其保存到名为example.java的文件中。
公共课范例{/*加载C DLL */静态{System.loadLibrary (“MATLAB_JNI”);}/*函数原型*/Public static native double[] kalmanfilter (双重的[]a);}
我们可以将调用添加到我们的函数中,但是在工作流的这一点上,我们只需要函数声明。我们将在步骤5中添加调用。
注意,结果数组是Java函数的返回值,而它是C函数的输出参数。
- 从保存的Java文件生成一个C头文件。
在我们的例子中,我们使用javahJava开发工具包中的工具。这个工具从包含本地方法的给定Java类创建C头文件。
我们运行以下MATLAB命令:
!javah示例% MATLAB命令
与MATLAB系统中的所有可执行文件命令一样,该文件javah.exe
必须由运行MATLAB的操作系统知道。在Windows上,这意味着环境变量PATH必须包含javah.exe
.
上面的命令将生成一个C头文件,其中包含以下JNI C函数声明:
JNIEXPORT jdoubleArray JNICALL Java_example_kalmanfilter(JNIEnv *, jclass, jdoubleArray);
-
为JNI C声明编写C实现代码。这个C包装器代码执行以下操作:
- 将JAVA类型数据转换为C类型数据
- 调用C函数
- 将C类型数据转换为JAVA类型数据
卡尔曼滤波器的包装器C代码如下所示:
JNIEXPORT jdoubleArray Java_example_kalmanfilter (JNIEnv *env, jclass cls, jdoubleArray a)/*C代码*/{jdouble临时[2];/ * 1。复制JAVA数组到C数组*/jdouble* ac = (*env)->GetDoubleArrayElements(env,a,0);/*创建新的JAVA数组*/jdoubleArray结果= (*env)->NewDoubleArray(env, 3);如果(result != NULL) {/*2.调用C函数*/kalmanfilter (ac,临时);/ * 3。将C数组复制到Java数组*/(*env)->SetDoubleArrayRegion(env,result,0,3,temp);}/*删除临时C数组*/(*env)->释放双数组元素(env,a,ac,0);返回结果;}
注意,Java类型本身被转换为JNI类型。事实上,双[]Java
数组类型显示为jdoubleArray
,而double Java类型则显示为jdouble类型。
表2显示了Java和Java JNI类型之间的等价性(有关更多信息,请参阅JNI类型和数据结构).
Java类型 | 原生类型 | 描述 |
---|---|---|
布尔值 | jboolean | 无符号8位 |
字节 | Jbyte | 签署了8位 |
烧焦 | jchar | 无符号16位 |
短的 | jshort | 签署了16位 |
Int | 吉特 | 有符号32位 |
长 | 琼 | 签署了64位 |
浮动 | jfloat | 32位 |
双重的 | jdouble | 64位 |
无效 | 无效 | N/A |
表2。Java和Java JNI数据类型。
-
构建jnicdll。DLL包括:
- 由MATLAB Coder在步骤1中创建的C源文件
- 控件创建的C JNI头文件javah步骤3中的工具
- 第4步中为JNI接口编写的包装器C代码
- 向Java代码中添加函数调用并编译它。
/* JAVA代码*/公共课范例{/*加载C DLL */静态{System.loadLibrary (“MATLAB_JNI”);}Public static native void初始化();Public static native double[] kalmanfilter (双重的[]a);公共静态无效main(String[] args) {example myM =新例();myM.initialize ();//初始化卡尔曼滤波器双重的[] ak = {1,2};双重的[] bk = myM.kalmanfilter(ak);//调用本机方法} }
注意一个的存在初始化
函数。该函数由MATLAB编码器创建。由于kalmanfilter
MATLAB函数使用持久变量。因此,我们需要声明和包装“initialize”函数。
- 运行Java代码。确保DLL文件位于与Java可执行文件相同的文件夹中。
这种方法的好处
我们已经概述了一个工作流,允许您将MATLAB算法部署到任何平台上,即使是不支持MATLAB的平台。万博1manbetx平台框架可以是C、c++或Java语言。
这种工作流程的好处是很多的。您不仅可以避免用另一种语言重写MATLAB代码的成本和测试翻译后的代码的成本,还可以节省开发时间并从MATLAB Coder获得生产质量的C代码。
1JNI技术不是在JAVA代码中调用本机C的唯一方法。您还可以使用称为JAVA本机访问(JNA)的技术。JNA需要使用额外的包。