将C MEX S函数链接到C ++代码
今天,我很乐意欢迎来宾博客
Navid Rahbariasr.
。Navid最近收到了从用户尝试在加速器模式中引用模型中包含C ++代码的用户的请求。不幸的是,这位用户被迫使用Matlab R2020B,并且无法利用新的
C ++金宝app支持模型参考仿真目标
添加在Matlab R2021A中。这是解决方法Navid提出。
- 吉利
配置S函数构建器以包含C ++代码
让我们从一个简单的例子开始,我们的s函数正在调用方法
得到
在自定义C ++源代码中定义。Header和Custom C ++代码的源代码如下:
请注意,“::”是C ++运算符。它被称为
范围决议算子
并且可用于访问全局变量时,当存在具有相同名称的本地变量时。所以,在这个例子中,我们有一个名为的全局变量
一种
,以及方法内具有相同名称的局部变量。通过添加::在前面
一种
我们表示我们对全局变量的兴趣
一种
,在此示例中的值为2.此运算符::未在C中定义,因此如果您尝试在C中编译此代码,则会获得语法错误。
我们在S-Function Builder的包含部分中包含自定义标题,如下所示:
我们称之为方法
得到
在S函数输出包装器功能中并将其分配给S函数块的输出:
我们将C ++源代码添加为库条目,以便S函数可以调用其中定义的方法。您可以在S-Function Builder接口底部找到库条目:
最后,我们构建S函数:
请注意,我们已将S函数的语言设置为C ++。如果我们将其设置为C,我们将收到该方法的错误
得到
是未解决的:
通过将语言设置为C ++,构建了S函数。现在,如果我们运行模型并检查输出,我们会看到输出为2,全局变量的值
一种
:
引用模型
如果我们在正常模式中引用上述模型,我们将获得预期的2。
但是,如果我们将模型块设置为Accelerator模式并尝试运行模型,我们会看到一个关于一个未解决的外部符号的错误,当S函数构建器语言设置为C而不是C ++时,看起来与上面所示的未得到解决的外部符号相似:
该错误表明Simulink找不到金宝app
sfcn_test_wrapper.c.
和
custom_code.c -
这是准确的,因为这些文件具有CPP扩展而不是C!这发生了,因为Simulink引擎首先为语言为C的加速器模式金宝app生成参考模型的仿真目标,因此它将符号解释为C而不是C ++,因此加速器模式构建无法与S-正确链接功能。
解决方法
如果我们希望加速引用模型成功构建,我们需要在C中编写S函数,但我们的源代码使用C ++功能,所以我们如何在C中编写S函数?
这个诀窍是将S-function链接到编译版本的源代码,所以编译器不需要重新编译它(它就像磨削C编译器的C ++食物那样没有右牙齿咀嚼它!)但可以C代码调用编译C ++方法?答案是肯定的,只要我们包装的C ++声明方法
extern c {}
,使编译器在编译方法时使用C命名约定。
我们首先通过extern c包裹方法修改自定义头文件,如下所示:
注意
#ifdef __cplusplus.
是一个编译器指令。它有效地意味着“如果语言是C ++ ......”。当我们编译源代码时,随着编译器检测到它是C ++,它将与方法声明包装
extern“c”{}
所以编译的对象将具有C命名方案。
现在,我们通过使用-c标志使用mex编译源代码到对象文件中:
mex -c custom_source.cpp.
通过运行此命令,您将获得一个对象文件
custom_code.obj.
在包含编译版本的文件夹中
custom_source.cpp.
:
现在我们转到S函数构建器并修改两件事:
1)将语言更改为c
2)将S-函数链接到编译的obj文件而不是未分册的源文件(惊喜!您可以将s-function链接到obj文件!)
当我们将S函数链接到编译的C ++代码而不是未申报的C ++代码时,可以使用C语言构建S函数。
现在,如果我们转到顶级模型并以加速模式运行模型,它将成功构建仿真目标,我们将获得2的预期输出:
基本上,我们能够将仅理解C语言的加速器构建链接到C MEX S函数和编译的C ++ OBJ文件:
C ++金宝app支持R2021A中的模型参考仿真目标
上述解决方案对于较旧版本很有用。在R2021A中,如果您的模型包括C ++ S函数,则可以简单地设置
语
在配置集的仿真目标部分中的C ++,这将允许加速器构建以了解C ++语言并正确解释C ++ S功能。
并且所有内容都使用C ++构建:
现在轮到你了
|
注释
要发表评论,请点击这里登录您的MathWorks帐户或创建新的。