生成独立的C/ c++代码来检测和报告运行时错误
在开发期间,在生成C/ c++代码之前,通过运行算法的MEX版本来测试生成的代码是一种最佳实践。但是,有些错误只发生在目标硬件上。要检测这些错误,可以生成独立的库和可执行文件来检测和报告运行时错误,比如超出范围的数组索引。
默认情况下,对独立库和可执行文件禁用运行时错误检测。为独立库和可执行文件启用运行时错误检测和报告:
在命令行中,使用代码配置属性
RuntimeChecks
.CFG = code .config(“自由”);'dll'或'exe'cfg。RuntimeChecks = true;codegen配置cfgmyfunction
在MATLAB®编码器™应用程序,在项目设置对话框中,在调试窗格中,选择生成运行时错误检查复选框。
运行时错误检测会影响生成代码的性能。如果性能是应用程序的考虑因素,那么不要生成启用了运行时错误检测的产品代码。
生成C代码vs.生成c++代码
如果目标语言是C,则生成的代码使用流
将错误消息写入stderr
.然后,代码使用中止
终止应用程序。如果流
而且中止
不可用,你必须提供它们。的中止
函数突然终止程序。如果您的系统支持信号,您可以捕万博1manbetx获中止信号(SIGABRT
)这样你就可以控制程序的终止。
如果目标语言是c++,则生成的代码会抛出std:: runtime_error
运行时错误的异常。调用生成的c++入口点函数时,可以使用类来捕获和处理这些异常试一试
-抓
块在你的外部c++代码。
但是,对于并行区域内的运行时错误检查(或parfor
循环或自动并行为
循环),生成的c++代码不会抛出异常。在这种情况下,生成的代码使用流
将错误消息写入stderr
,然后使用中止
终止应用程序。要了解有关自动并行化的更多信息,请参见自动并行化生成代码中的循环.
示例:比较生成的包含运行时检查的C和c++代码
在本例中,您将比较一个MATLAB®函数生成的C和c++代码的运行时行为,该函数计算其输入参数的平方根。生成的代码只能接受非负的实值,并对负输入产生运行时错误:
生成的C代码使用
流
将错误消息写入stderr
.然后,代码使用中止
终止应用程序。生成的c++代码抛出一个
std:: runtime_error
此运行时错误的异常。在编写用来调用生成函数的c++ main函数中,可以使用类来捕获和处理此异常试一试
-抓
块。
定义MATLAB函数
定义MATLAB函数errorCheckExample
在一个单独的文件中。这个函数计算输入参数的平方根:
类型errorCheckExample
function y = errorCheckExample(x) y = sqrt(x);结束
生成C库和可执行文件
生成一个动态链接的C库errorCheckExample
它接受双标量输入。属性使用代码配置对象RuntimeChecks
参数设置为真正的
.此外,使用- d
选项,将代码生成文件夹命名为codegen_c_dll
.
CFG = code .config(“dll”);cfg。RuntimeChecks = true;codegen配置cfgerrorCheckExamplearg游戏1- dcodegan_c_dll报告
要查看报告,请打开('codegan_c_dll/html/report.mldatx')
打开代码生成报告并检查文件errorCheckExample.c
.为MATLAB函数生成的C函数具有签名double errorCheckExample(双x)
.要计算平方根,errorCheckExample
调用√6
只计算实平方根的库函数。所以,errorCheckExample
只能接受正输入。对于负输入,errorCheckExample
调用生成的实用程序函数rtErrorWithMessageID
使用流
将错误消息写入stderr
然后使用中止
终止应用程序。
static void rtErrorWithMessageID(const int b, const char *c, const char *aFcnName, int aLineNum) {fprintf(stderr, "域错误。要从实际x计算复杂结果,使用" "\'%.*s(complex(x))\'.", b, c);流(stderr,“\ n”);fprintf(stderr, "错误在%s(行%d)", aFcnName, aLineNum);流(stderr,“\ n”);。fflush (stderr);abort ();}
在生成库代码时,代码生成器还生成示例主文件main.h
而且c
在例子
生成文件夹的子文件夹。支持的C万博1manbetx文件main_runtime_check.h
而且main_runtime_check.c
是这些示例文件的修改版本。修改后的主要
函数调用errorCheckExample (4)
,这会产生一个运行时错误。
运行这些命令,使用修改后的主文件生成一个C可执行文件。命名代码生成文件夹codegen_c_exe
.命名可执行文件errorCheckExample_c
通过使用- o
选项中的codegen
命令。
CFG = code .config(exe”);cfg。RuntimeChecks = true;cfg。CustomSource =“main_runtime_check.c”;cfg。CustomInclude = pwd;codegen配置cfgmain_runtime_check.cmain_runtime_check.herrorCheckExamplearg游戏1- oerrorCheckExample_c- dcodegen_c_exe
代码生成成功。
运行生成的可执行文件。注意,它会打印在实用程序函数中硬编码的错误消息rtErrorWithMessageID
.
如果isunix系统(”。/ errorCheckExample_c ');elseifispc系统(“errorCheckExample_c.exe”);其他的disp (“不支持平台”万博1manbetx);结束
域的错误。使用'sqrt(complex(x))'从实际x计算复杂结果。根号错误(第13行)./errorCheckExample_c: Aborted
生成c++库和可执行文件
生成动态链接的c++库errorCheckExample
它接受标量双输入。属性使用代码配置对象RuntimeChecks
参数设置为真正的
.此外,使用- d
选项,将代码生成文件夹命名为codegen_cpp_dll
.
CFG = code .config(“dll”);cfg。RuntimeChecks = true;codegen配置cfg朗:c++errorCheckExamplearg游戏1- dcodegen_cpp_dll报告
要查看报告,请打开('codegen_cpp_dll/html/report.mldatx')
打开代码生成报告并检查文件errorCheckExample.cpp
.类似于前一节中生成的C函数,errorCheckExample
只能接受正输入。对于负输入,errorCheckExample
调用实用函数rtErrorWithMessageID
.但在这种情况下,效用函数抛出std: runtime_error
异常,您可以捕获和处理在您的手写主要
函数。
static void rtErrorWithMessageID(const char *b, const char *aFcnName, int aLineNum) {std::stringstream outStream;((outStream << "域错误。使用\'")<< b) << "(complex(x))\'.";outStream << "\n";((((outStream < <“错误”)< < aFcnName) < <(行)< < aLineNum) < <“)”;把std:: runtime_error (outStream.str ());}
在生成库代码时,代码生成器还生成示例主文件main.h
而且c
在例子
生成文件夹的子文件夹。支持的c万博1manbetx++文件main_runtime_check.hpp
而且main_runtime_check.cpp
是这些示例文件的修改版本。修改后的main ()
函数调用errorCheckExample (4)
在一个try - catch
块。该块捕获异常,并通过预挂字符串打印修改后的消息被抓住的感叹:“
到被捕获的异常所包含的消息。
运行这些命令,使用修改后的主文件生成一个c++可执行文件。命名代码生成文件夹codegen_cpp_exe
.命名可执行文件errorCheckExample_cpp
.
CFG = code .config(exe”);cfg。RuntimeChecks = true;cfg。CustomSource =“main_runtime_check.cpp”;cfg。CustomInclude = pwd;codegen配置cfg朗:c++main_runtime_check.cppmain_runtime_check.hpperrorCheckExamplearg游戏1- oerrorCheckExample_cpp- dcodegen_cpp_exe
代码生成成功。
运行生成的可执行文件。观察到它打印了修改后的错误消息。
如果isunix系统(”。/ errorCheckExample_cpp ');elseifispc系统(“errorCheckExample_cpp.exe”);其他的disp (“不支持平台”万博1manbetx);结束
捕获的异常:域错误。使用'sqrt(complex(x))'从实际x计算复杂结果。根号错误(第13行)
限制
独立代码中的运行时错误检测和报告有以下限制:
错误信息只有英文。
一些错误检查需要双精度支持。万博1manbetx因此,运行生成代码的硬件必须支持双精度操作。万博1manbetx
如果程序终止,错误检测和报告软件不会显示运行时堆栈。要检查堆栈,请附加一个调试器。
如果生成的C代码终止,错误检测和报告软件不会释放资源,例如分配的内存。生成的c++代码没有这个限制。如果生成的c++代码终止,分配的内存和其他资源将被释放。
在独立代码中,函数
错误
显示一条指示发生错误的消息。来查看指定的实际消息错误
时,必须生成并运行MEX函数。在独立代码中,如果使用多个参数调用函数
断言
不会报告错误,也不会终止执行。例如,如果使用单个参数调用,断言(电导率)
,如果气孔导度
不是常数真正的
值,报告错误并终止执行。
另请参阅
codegen
|编码器。CodeConfig
|编码器。EmbeddedCodeConfig