最近接触了几个LabVIEW通过MATLAB Script调用.m脚本文件的案例,调试过程中遇到了很多的问题,现在对这些问题的解决办法做个总结,也备忘一下。
路径设置问题在MATLAB环境下运行的好好的.m文件,在LabVIEW中死活运行不起来,一个最经常遇到的问题就是路径设置问题,路径设置问题一般又分好几种情况:
在MATLAB中,双击打开m文件后,自然就把当前文档目录作为了工作目录,通过pwd函数就可获得当前工作目录路径。
pwd函数获取当前文件夹路径
但是在LabVIEW中通过MATLAB Script调用时千万要注意,它返回的不是调用VI或者脚本文件所在的当前文件夹,而是MATLAB的安装路径,可通过MATLAB Cammand Window中看出,如下图所示。
通过LabVIEW调用时,pwd函数返回的是MATLAB安装路径
因此,如果在脚本文件中有使用相对路径,或者有用到了pwd函数来获取当前工作文件夹路径,就要注意一定要进行修改了,一般可通过如下步骤进行修改:
1)通过MATLAB Script中添加输入端子,并将数据类型设置为路径,再通过LabVIEW的路径控件将LabVIEW当前工作目录传递给MATLAB Script;
2)通过addpath函数将传递进来的文件夹路径添加至当前MATLAB会话的顶层;
3)通过fullfile函数建立以当前工作目录为基础的完整文件路径。
路径设置示例
addpath函数帮助文档
fullfile函数帮助信息
函数声明问题在MATLAB的m文件的主文件中是可以声明其它函数的,并且可以直接运行没有任何问题。
在m文件主文件中声明函数
但是如果把相同的脚本文件内容通过LabVIEW的MATLAB Script运行的话,就会报出1050错误了,意思大概就是说不允许在MATLAB Script中进行函数定义,需要在代码文件(另外的m文件)中创建函数。
解决办法自然就是将函数定义部分内容迁移至m文件中即可。
MATLAB Script中不能直接进行函数定义
最近在开发一个项目时,已经用C语言写好了主要算法部分,并将主要功能实现部分以函数形式封装到了动态连接库DLL文件中,但客户要求提供Matlab调用DLL函数的例子,因此,花了点时间研究了下Matlab语言中调用DLL函数的方法。
为简单起见,下面以DLL文件中的一个简单的函数调用为例进行说明(当然是虚构的一个函数了,但也涉及到了常用参数类型如指针、字符串等的传递)。
2、DLL文件中函数原型说明本例调用C语言编写的DLL文件“MyDll.dll”里的函数“MyFunc”,这个函数原型声明如下:
#define EXPORT extern "C" __declspec(dllexport)void MyFunc(double x0, double deltx, int length, double *y, double &lastData, char* status);
该函数产生一个初始值为x0、间隔为deltx、长度为length的一维数组y,并给出该数组的最后一个值lastData和函数的运行状态信息status。从函数的声明中可以看出,该函数中参数数据类型涉及到了“double”类型、“int”类型和“char”类型(字符串类型),在参数传递中也涉及到了值传递(x0、deltx、length)和指针(y、lastData、status)传递方式,较为复杂。为便于理解,下面给出该该函数的C语言实现代码。
/*------------------------------------------------------------------------------- *产生等间隔的数据向量并返回数据向量的最后一个值和状态信息 *输入:x0--起始值 *deltx--数据间隔 *length--数据长度 *输出:y--产生的向量 *lastData--y数组的最后一个值 *status--状态信息------------------------------------------------------------------------------- */void MyFunc(double x0, double deltx, int length, double *y, double &lastData, char* status){ for (int i=0; i<length; i++){y[i] = x0 + i * deltx;}lastData = y[length-1];strcpy(status, "ok!");}3、Matlab调用方法
对于上面的MyFunc函数,在Matlab中调用主要涉及到了几个函数的使用,包括loadlibrary/unloadlibrary、libpointer、calllib等函数的使用,分别实现加载/卸载动态库、定义指针变量、调用函数等功能。
其Matlab中的调用代码如下所示:
clc, clear allloadlibrary('MyDll.dll','MyDll.h');libfunctions MyDll -full;x0 = 0;deltx = 1.1;length = 10;pY = libpointer('doublePtr',zeros(1,length));pLastData = libpointer('doublePtr', 1.0);pStatus = libpointer('cstring', '');[~, ~, status] = calllib('MyDll','MyFunc', x0, deltx, length, pY, pLastData, pStatus);disp(['y: [', num2str(pY.value), ']']);disp(['lastData: ', num2str(pLastData.value)])disp(['status: ', status])unloadlibrary MyDll
其中,通过代码“libfunctions MyDll -full;”可以显示dll文件中所有的函数信息。
运行结果如下图所示:
可见,在Matlab中已经成功调用了dll文件中的MyFunc函数并得到了正确的运行结果。
4、备注在使用calllib函数运行dll文件中的函数时,当参数中传递字符类型的指针变量(char *)时,其对应的变量如上例中pStatus的值不会改变,必须通过calllib的返回值得到更新后的值。
本文由编码那些事原创,请关注+转发+收藏+点赞,带你一起长知识!
Matlab 中,对变量的定义不需要像 C/C++或Java语言那样,必须先要进行定义,然后才能引用、赋值。Matlab 中可以直接对变量进行赋值,无需声明定义,而且数据类型可以随时改变,也就是说Matlab对数据变量是自动识别和控制的。
Matlab 对变量名的规定比较宽松,要求包括:
以字母开头;长度不能超过63个字符;区分大小写。Matlab环境下,有三种变量:
Local Variables:局部变量,如果变量不声明,则默认;Global Variables:全局变量,可以被多个不同的函数调用,通过global x声明x为全局变量,在其他函数中调用该全局变量时,也需要加上global x,声明x为全局变量;Persistent Variables:永久变量,类似C/C++中的常数,在程序运行期间值不可改变,如Matlab内置的pi、inf、nan、eps。Matlab 中的函数名和内置关键字不可作为变量。关于字符串是否能作为变量名,可以使用isvarname函数进行检查。Matlab的内置关键字包括:
‘while’,‘for’,‘break’,‘continue’‘if’,‘elseif’,‘else’,‘end’‘switch’,‘case’,‘otherwise’‘try’,‘catch’‘function’,‘global’,‘persistent’,‘return’