概述
楔子
本指南试图帮助用户写出在转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”。
最后
以上就是幽默流沙为你收集整理的MATLAB转C/C++常见问题总结楔子注意点其他总结的全部内容,希望文章能够帮你解决MATLAB转C/C++常见问题总结楔子注意点其他总结所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复