MATLAB转C/C++常见问题总结

您所在的位置:网站首页 matlab中常见的错误 MATLAB转C/C++常见问题总结

MATLAB转C/C++常见问题总结

#MATLAB转C/C++常见问题总结| 来源: 网络整理| 查看: 265

楔子

本指南试图帮助用户写出在转C过程中尽量少报错的Matlab m文件,其中更多是一些编程范式上的问题,在此记录下来,帮助后人写出无缝转C的代码。

Author: Y. F. Zhang

Time: 2022.4.16

注意点 使用变量前声明变量

这一点在matlab中时可以容忍的,但对于一般编程语言是无法容忍的。使用一个变量前请预分配变量内存(注意预分配内存不是简单前面给个 =0就可以了,得是相应维度的预分配):

tmp = zeros(6, 6); % 预分配内存 for i = 1 : 6 tmp(:, i) = ones(6, 1); end m文件中内联嵌套scripts

不要这么干不要这么干不要这么干… 目前转c是不支持内联嵌套scripts的:

% main.m a = 2; b = zeros(3, 3); init_para; % init_para.m 为scripts % others % others...

有多种方案解决,例如:

将init_para代码内联进来(也就是直接复制过来);将init_para写成无参函数调用; 不允许离开变量作用域后使用变量

在matlab中对变量的作用域这个概念弱化了许多,下面这段代码在matlab下是能正常运行的:

for i = 1 : 100 % do something end plot([i, i + 1], [10, 11]);

变量 i 在离开了for循环作用域后继续使用,这在c是不允许的。

不允许动态分配内存语法

matlab下常用动态分配数组语句:

array = []; for i = 1 : 100 array = [array, i]; end

这种语法转c报错,如果想达到相同效果(预分配可能导致剩余部分0,但实际却不需要它们),可以使用如下方法:

array = zeros(1, 1000); i = 0; for i = 1 : 1000 if done, break; end % done用于判断结束 array(i) = i; end tmp_array = zeros(1, i); tmp_array = array(1 : i); 不要用load

load转不了,或者说io类函数可能都转不 了。

别使用matlab的高级函数

例如: care fsolve等等,若要使用,只能从底层自己实现了。

解决这个真的是纯纯的运气活加体力活,能否解决取决于google有没有相同案例,大多数替代包都发布linux版本。就算能替代,首先需要将m文件中对应语句注释掉后转c然后还要去转出来的代码中定位该语句,之后还要把包移植过来解决接口输入输出,最后还要测试…

函数返回值要确保逻辑有值 function y = foo() flag = 1; if flag == 1 y = 2; end end

像上面这种代码虽然y一定等于2输出,但逻辑上没有在else中对y赋值就是存在歧义的。解决方法在一开始对y赋值0。

深度学习转C

LSTM转mkldnn转不了,arm树莓派可以,要用网上的《xxxLSTM c实现》很难,除非你对LSTM的每个细节了如指掌…

一个m函数文件写一个函数

在matlab中一个m写多个函数是允许的,方便函数内部调用,但转c过程中会出错。解决方案:

内联地将内部函数复制到调用地方;重新建立一个m文件(推荐); 注释掉一些没用的代码

包括但不限于:

画图相关代码;与业务逻辑无关的打印代码;et.al 尽量少用global

matlab转c目前也是支持global的,只需要在转前添加函数中所有global变量,并定义其维度、类型以及初始值(若未定义,在使用之前必须初始化),注意以下情况是不允许的:

在事先添加了global x和y的前提下,对y进行了初始化而未对x初始化,之后直接在函数中令x = y。这在matlab中是允许的,但转c是会出错的。

使用global会严重影响代码的可阅读性和封装性,一个实现某一功能的特定函数若使用了global变量,会影响它无缝移植到另外相同问题上,另外使用global变量之前很难定位上一个修改它的代码段,会增强程序之间的耦合性。

若执意使用global,在转c的prj文件中请初始化所有global变量为任意值(zeros就行),并在使用它前赋予真正的值。否则会出现许多size mismatch报错。使用global的程序员大都想减少函数的大量传参,可以考虑使用参数句柄的方式传参,并输出修改后的参数句柄。function out_para_bar = func(in_para_bar) % others logged_signals = func(logged_signals); % others 其他 编程习惯 写完一份m后 ctrl A右键选择 智能缩进让所有代码快速缩进一下,否则看起来很凌乱。一些必要的空格,例如 tmp = [2, 3, 4]; for i = 1 : 100 使代码整体美观。不需要的函数输出用 ~代替。预分配内存。 tmwtypes.h

转完后的代码至少缺少tmwtypes.h这个头文件,在matlab->extern->include目录下将其拷贝到自己的工程中(或者直接配置vs include目录)。

转c++设置

若转c++,在设置中将标准设为c++11,但这不是必须的。

修改报错代码

每进行一次对m的大修(在转c过程中修改报错),回到m中重新运行一下代码看修改是否影响原本代码的运行结果。否则容易出现修改很多地方后原本代码都运行出错的情况。

总结

“尽量用底层语言的编程思维来写matlab”。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3