How to import external c types with namespaces?
49 次查看(过去 30 天)
显示 更早的评论
Tobias Pape
2022-6-22
I try to import external c header files to my simulink model.
I am using the function ImportExternalCTypes() (Matlab2021b) to import the header file.
Call of the function:
Simulink.importExternalCTypes('test.h', 'Language', 'C++', 'Overwrite', 'on', 'DataDictionary', 'Types.sldd')
Content of the header file test.h:
#include <string>
#include <vector>
#include <stdexcept>
namespace System {
namespace Command {
enum Type {
On,
Off
};
}
enum class Subystem {
Stop,
Start
};
The enumeration within the namespace will be ignored.
Only the enumeration Subystem will be added to the Data Dictionary.
Is there a wag that Matlab recognizes the Enumeration within the namespace?
I get an auto generated header file with the namespaces. All Enumerations are defined within namespaces in the original header file.
回答(2 个)
Nitanshu
2022-6-28
1 个评论
Tobias Pape
2022-7-4
Hi Nitanshu,
thank you for your answer. I already read the documentation.
The documentation does not explain why namespaces will be ignored.
Yao Ren
2023-5-9
Importing struct and enum types inside of C++ namespaces is supported in R2023a. Please upgrade to MATLAB R2023a.
22 个评论
Yao Ren
2024-1-12
编辑:Yao Ren
2024-1-12
The documentation page for Simulink.importExternalCTypes is listed below
It does not specifically explain how to import types under C++ namespaces as the workflow should just work using the documented options. (Types under namespaces not being imported was a limitation prior to release R2023a)
To try it, please use MATLAB release R2023a or later.
1) Copy paste the following sample C++ header code into a file named "test.h". Notice there are two enum types "Subystem", and "Type", which is inside of namespace "System::Command::"
#include <string>
#include <vector>
#include <stdexcept>
namespace System {
namespace Command {
enum Type {
On,
Off
};
}
}
enum class Subystem {
Stop,
Start
};
2) In MATLAB command windows, run the following command. Make sure you have a mex compiler set up for C++ by running command "mex -setup C++" prior to running "Simulink.importExternalCTypes"
>> Simulink.importExternalCTypes('test.h', 'Language', 'C++', 'DataDictionary', 'Types.sldd')
3) Notice a Simulink Data Dictionary file "Types.sldd" is created in current directory. Double click the sldd file to open it up and observe enum types "Type" and "Subystem" imported under "Types > Design Data" section.
4) If you'd like the enum types imported as enum class M files in current folder. Run the command without "DataDictionary" option
>> Simulink.importExternalCTypes('test.h', 'Language', 'C++')
5) Check two enum class M files are generated, "Type.m" and "Subystem.m". The content of "Type.m" is pasted here.
classdef Type < Simulink.IntEnumType
% MATLAB enumeration class definition generated from template
enumeration
On(0),
Off(1)
end
methods (Static)
function defaultValue = getDefaultValue()
% GETDEFAULTVALUE Returns the default enumerated value.
% If this method is not defined, the first enumeration is used.
defaultValue = Type.On;
end
function dScope = getDataScope()
% GETDATASCOPE Specifies whether the data type definition should be imported from,
% or exported to, a header file during code generation.
dScope = 'Imported';
end
function desc = getDescription()
% GETDESCRIPTION Returns a description of the enumeration.
desc = '';
end
function headerFile = getHeaderFile()
% GETHEADERFILE Specifies the name of a header file.
headerFile = 'test.h';
end
function flag = addClassNameToEnumNames()
% ADDCLASSNAMETOENUMNAMES Indicate whether code generator applies the class name as a prefix
% to the enumeration.
flag = false;
end
end
end
Brandon
2024-1-16
编辑:Brandon
2024-1-16
There are two issues here.
1) Importing C++ enums that reside inside namespace (which I can confirm does work fine in R2023a)
2) Generating code from a Simulink model that uses this enum. This does not seem to work (in R2023a at least) because the generated code does not prepend the enum types or enum values with the original namespace. Indeed the "Type.m" matlab enum file you show above does contain any information about the original namespace, so there's no way for the generated code to know that it should be namespacing that enum. Ergo, this seem like a broken workflow in matlab.
Yao Ren
2024-1-18
编辑:Yao Ren
2024-1-18
Regarding issue 2), we are currently developing a feature that will introduce the concept of "namespace" to Simulink modeling. With this feature, the function Simulink.importExternalCTypes() will be capable of importing a C data type as a Simulink type into the Simulink Data Dictionary (.sldd), organizing them under the appropriate namespaces. This will ensure that model code generation can properly recognize and utilize these namespaces.
In the meantime, for users of R2023a or later, there is a workaround that allows the generation of C++ code from a model in such a way that the generated code respects the namespaces of the imported C++ data types.
Please follow the steps below to apply this workaround:
1) Navigate to model's "Configuration Parameters" and then to the "Simulation Target" section. Here, you need to include the C++ code headers containing the types in the "Include headers" field. It's important to ensure that the "Include directories" field lists all the directories needed to search for any header files that are directly or indirectly included. If all headers are located in the current working directory, this field can be left empty, as the current directory is always included in the search path by default. Note that the "Include directories" can be specified as relative paths to the location of the model file. The screenshot below demonstrates how to enter the include headers, using the previous "test.h" example as a reference.

The model will parse the header files specified in step 1) and recognize all the types, such as "enum Type" from our example, noting that it is encapsulated within the "System::Command::" namespace.
2) Ensure that the Code Generation "Language" is set to "C++". If you are importing enum class types, also make sure that the "Language standard" is set to "C++11 (ISO)".

3) Proceed with generating the code for your model. The code generation process will be able to match the imported Simulink.EnumType "Type" with the C++ data type "System::Command::Type" found in "test.h". Consequently, it will generate the correct code that includes namespaces for type references.



By following these steps, you should be able to generate C++ code that honors the namespaces of imported C++ data types, even before the new feature is officially released.
Fe
2024-7-29
thanks for the workaround explanation! Are there any updates on the official fix that does not require the workaround?
Yao Ren
2024-8-28
编辑:Yao Ren
2024-8-29
Hello @Fe @Marcus, we may be able to support this workflow in R2025a release (roughly 6 months from now). It requires C/C++ types being imported into a Simulink Data Dictionary (SLDD). To use these imported types in a model, model has to link to the SLDD. Is this requirement ok with you? If you have additional requirements, please post them here. Thanks!
Marcus
2024-8-29
That works for us. We can support and test this feature in the prerelease if you need any feedback on this new feature.
Marcus
2025-1-20
编辑:Marcus
2025-1-20
@Yao Ren Hi i tried this in the 2025 pre release, but the cppnamespaces is not filled in when importing .h files with c++ namespaces into the *.sldd file. And with that the generation of code get the exact same behaviour as before. Is it expected to work now?
It also complains when one have mutiple types of the same name under different namespaces. But this should not be needed since that can be expected because of the namespaces.
I also noticed that if a enum class consist of a element call "all" the import crashes.
Also the import time is subtantialy longer, which i hope is not the case in the released version.
One last thing, if one want to use same enums in different *.sldd this is not supported right now.
Yao Ren
2025-1-22
@Marcus Are you using the new 'DataDictionarySection' parameter in your command? Recording namespaces of a C++ type only works when importing type into "ArchitecturalData" section. For example,
Simulink.importExternalCTypes('myHdr.h','Language','C++', 'DataDictionary','myDict.sldd','DataDictionarySection','ArchitecturalData');
Another question is, are you generating code for GRT or ERT? ERT should have type namespaces emitted. GRT does not work in pre-release.
Marcus
2025-1-22
编辑:Marcus
2025-1-22
@Yao Ren Thank you for your reply. Yes i had missed that you needed to also put in 'DataDictionarySection','ArchitecturalData' Now the namespaces can be seen in the ArchitecturalData view. unfortunately i cannot for some reason compile with the embedded code (i.e ERT). I get the following error "modelname.rtw Line: 601 Column: 17 syntax error"
The import is really slow to the *.sldd file and i think this realy need do be optimized to be a usefull tool.
Also when importing i get the following message "because there are multiple types of the same name under different namespaces. Specify only one type using "Names" option with the namespace qualified type name." Which should not be needed since that the whole point of using namespaces.
I will continue to test importing multiple h files that have includes to the the same h file with the definitions of enumerations.
Yao Ren
2025-1-22
Thanks for reporting these issues! Please see my comments below:
Error: "modelname.rtw Line: 601 Column: 17 syntax error".
This appears to be an ERT code generation issue. We hope it will be resolved in the general release.
Slow Import to .sldd File.
I attempted to reproduce the import speed issue and compared it with version 24b. In my tests, importing to the DesignData section of the data dictionary is twice as slow in version 25a. Importing to the ArchitecturalData section is five times slower compared to importing to the DesignData section in 24b. However, this isn't a direct comparison since the ArchitecturalData section is a new feature in 25a. Are you experiencing similar slowdowns? Note that keeping the Data Dictionary open during import can increase the time, particularly when the ArchitecturalData section is visible. The UI rendering during type creation can be time-consuming. We will conduct profiling and aim to optimize the speed for the general release.
Error Message: "because there are multiple types of the same name under different namespaces. Specify only one type using 'Names' option with the namespace-qualified type name."
If you have two types, "ComponentA::Settings_t" and "ComponentB::Settings_t", in header files, Simulink can only have one Simulink Type named "Settings_t" in scope at a time. A single data dictionary can contain only one "Settings_t" type, which is why this error occurs. You can import only one of the two types by using 'Name', 'ComponentB::Settings_t' to remove the ambiguity. This is a known limitation not addressed in 25a. Simulink has plan to introduce native namespaces for modeling, allowing one data dictionary to hold two types named "Settings_t" in different Simulink namespaces.
Question: In your use case, do you need to use both "ComponentA::Settings_t" and "ComponentB::Settings_t" types in one model?
Enum Class with Element Named "all" Causes Import Crash.
We will reproduce this issue and fix it in the general release.
Marcus
2025-1-23
编辑:Marcus
2025-1-23
Hi @Yao Ren
Regarding Slow Import to .sldd file i got the following metrics
2025a
Simulink.importExternalCTypes('myHeader.h', 'Language', 'C++', 'DataDictionary', 'myDictionary.sldd', 'DataDictionarySection','ArchitecturalData');
Elapsed time: 104,36 seconds
2025a
Simulink.importExternalCTypes('myHeader.h', 'Language', 'C++');
Elapsed time: 2.16 seconds
2024a
Simulink.importExternalCTypes('myHeader.h', 'Language', 'C++');
Elapsed time: 1.91 seconds
As you can see it is a magnitude of 50 times the time of a standard importExternalCTypes which will make this tool tedious to use.
Regarding Error Message: "because there are multiple types of the same name under different namespaces. Specify only one type using 'Names' option with the namespace-qualified type name."
Yes right now we need to do workarounds for handling this. But from our side i would say that simluink handles this correctly is a requirement to make the most of c++ as the generation target language.
Tomorrow i will report how the import of mutiple headers with the same enumerations header file test is going.
Yao Ren
2025-4-4
The speed issue has been fixed in the upcoming R2025a release at mid May.
In the case of multiple same named types under different namespaces, only one is allowed to be imported to a data dictionary. This limitation still presents in R2025a. A workaround needs to be applied.
Yao Ren
2025-5-14
Let's use the previous example, there are two C++ types "ComponentA::Settings_t" and "ComponentB::Settings_t". Simulink.importExternalCTypes() imports both as Simulink types with their fully qualified names, "ComponentA__Settings_t" and "ComponentB__Settings_t". In addition, the command also generates a header file that contains Simulink type name alias to the original C++ types signatures.
sl_type_alias.h
using ComponentA__Settings_t = ComponentA::Settings_t;
using ComponentB__Settings_t = ComponentB::Settings_t;
In order to use these types in your models, "sl_type_alias.h" must be included in "Model configuration parameters > Simulink Target OR Code Generation (dependent on the use case) > Custom Code > Include headers" section.
Does this proposal align with your workflow?
Marcus
2025-5-27
Hi Yao Ren,
have you abandoned the SLDD solution?
Your suggestion feels like a short-term fix and not incorporation how c++ works. My suggestion is the following.
Same example there are two C++ types "ComponentA::Settings_t" and "ComponentB::Settings_t". Simulink.importExternalCTypes() imports both as Simulink types. as follows.
namespace ComponentA %Or ComponentB
classdef Settings_t < Simulink.IntEnumType
% MATLAB enumeration class definition generated from template
enumeration
SettingA(0),
SettingB(1)
end
methods (Static)
function defaultValue = getDefaultValue()
% GETDEFAULTVALUE Returns the default enumerated value.
% If this method is not defined, the first enumeration is used.
defaultValue = Settings_t.SettingA;
end
function dScope = getDataScope()
% GETDATASCOPE Specifies whether the data type definition should be imported from,
% or exported to, a header file during code generation.
dScope = 'Imported';
end
function desc = getDescription()
% GETDESCRIPTION Returns a description of the enumeration.
desc = '';
end
function headerFile = getHeaderFile()
% GETHEADERFILE Specifies the name of a header file.
headerFile = 'Enums.h';
end
function flag = addClassNameToEnumNames()
% ADDCLASSNAMETOENUMNAMES Indicate whether code generator applies the class name as a prefix
% to the enumeration.
flag = false;
end
end
end
end
The namespace as in c++ is optional when creating a classdef and is only present if the user wants it or namespace is present in the c++ file which is imported.
The usage in simulink is then ComponentA.Settings_t.SettingA or as you suggested ComponentA__Settings_t.SettingA. With this no extra include is needed and matlab supports how c++ is intended to be used. Also when we generate the namespace is already known so it will then become ComponentA::Settings_t
Note that if this is used the character length of only 63 characters must be expanded in my opinion. Otherwise, we will get allot of issues when namespace is added into simulink.
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Data Representation in Generated Code 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!发生错误
由于页面发生更改,无法完成操作。请重新加载页面以查看其更新后的状态。
您也可以从以下列表中选择网站:
如何获得最佳网站性能
选择中国网站(中文或英文)以获得最佳网站性能。其他 MathWorks 国家/地区网站并未针对您所在位置的访问进行优化。
美洲
- América Latina (Español)
- Canada (English)
- United States (English)
欧洲
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom(English)
亚太
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)