MATLAB转C/C++常见问题总结 |
您所在的位置:网站首页 › matlab中常见的错误 › MATLAB转C/C++常见问题总结 |
楔子
本指南试图帮助用户写出在转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); 不要用loadload转不了,或者说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。 深度学习转CLSTM转mkldnn转不了,arm树莓派可以,要用网上的《xxxLSTM c实现》很难,除非你对LSTM的每个细节了如指掌… 一个m函数文件写一个函数在matlab中一个m写多个函数是允许的,方便函数内部调用,但转c过程中会出错。解决方案: 内联地将内部函数复制到调用地方;重新建立一个m文件(推荐); 注释掉一些没用的代码包括但不限于: 画图相关代码;与业务逻辑无关的打印代码;et.al 尽量少用globalmatlab转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 |