【问题标题】:How to pass structures into re-integrated autogenerated C++ code in Matlab如何将结构传递到 Matlab 中重新集成的自动生成的 C++ 代码中
【发布时间】:2021-06-05 16:51:50
【问题描述】:

我正在尝试测试一些从 Matlab 生成到 C++ 中的代码。

为此,我尝试将生成的 C++ 代码集成并运行回 Matlab。

这是我尝试使用的函数(在 Matlab pre-autogen 中)

function out = getRotationMatrix(aStruct)

out = aStruct.bank_rad*aStruct.heading_rad+aStruct.pitch_rad;

end

我用这个自动生成它...

function varargout = AutoGenCode(varargin)
% Here we are attempting to generate a C++ class from a matlab function via a
% hosting function

% initialise
varargout = {};

% create instance of  config object
cfg = coder.config('LIB');
% config options
cfg.MaxIdLength                  = int32(64);
cfg.TargetLang                   = 'C++';
cfg.CppPreserveClasses           = 1;
cfg.EnableCustomReplacementTypes = true;
cfg.ReplacementTypes.uint32      = 'uint32_t';
cfg.CppInterfaceStyle            = 'Methods';
cfg.CppInterfaceClassName        = 'FrameTransformation';
cfg.FilePartitionMethod          = 'MapMFileToCFile'; % or 'MapMFileToCFile' SingleFile
cfg.EnableVariableSizing         = false;
%cfg.PreserveVariableNames        = 'UserNames'; % Worse
%cfg.IncludeInitializeFcn         = true;
cfg.PassStructByReference        = true;

thisStruct.bank_rad = 2.1;
thisStruct.heading_rad = 3.1;
thisStruct.pitch_rad = 3.1;

codegen -config cfg getRotationMatrix -args {thisStruct} -report -preservearraydims -std:c++11

end

要移动到另一个区域(\解压缩),我使用 packNGo

load([pwd,'\codegen\lib\getRotationMatrix\buildInfo.mat'])

packNGo(buildInfo,'packType', 'hierarchical','fileName','portzingbit')

现在当我尝试重新集成它时,我正在使用 clib

cd 'D:\thoros\Components\Frame Transformation Service\FT_V2\unzippedCode'
clibgen.generateLibraryDefinition('FrameTransformation.h','Libraries',{'getRotationMatrix.lib'})
build(defineFrameTransformation)
addpath('D:\thoros\Components\Frame Transformation Service\FT_V2\unzippedCode\FrameTransformation')

我必须在 defineFrameTransformation.mlx 中手动将 参数定义为 1

当我尝试使用该函数时,我无法在没有错误的情况下传递结构

A = clib.FrameTransformation.FrameTransformation()
thisStruct.bank_rad = 2.1;
thisStruct.heading_rad = 3.1;
thisStruct.pitch_rad = 3.1;
>> A.getRotationMatrix(thisStruct)

我收到以下错误

Unrecognized method, property, or field 'getRotationMatrix' for class 'clib.FrameTransformation.FrameTransformation'.

如果重写并重新生成函数以接受非结构输入,例如双倍。

通过使用汇总函数,我可以看到对 getRotationMatrix 的调用应该是 clib.FrameTransformation.struct0_T 类型的

但是我似乎无法创建这种类型的变量。

summary(defineFrameTransformation)

MATLAB Interface to FrameTransformation Library

Class clib.FrameTransformation.struct0_T

  No Constructors defined

  No Methods defined

  No Properties defined

Class clib.FrameTransformation.FrameTransformation

  Constructors:
    clib.FrameTransformation.FrameTransformation()
    clib.FrameTransformation.FrameTransformation(clib.FrameTransformation.FrameTransformation)

  Methods:
    double getRotationMatrix(clib.FrameTransformation.struct0_T)

  No Properties defined

那么应该如何在 Matlab 中将结构传递给 C++ 库?我做错了什么。

注意 Matlab 2020B、windows、Visual Studio 2019

【问题讨论】:

    标签: c++ matlab structure matlab-coder


    【解决方案1】:

    如果您有 Embedded Coder(cfg.ReplacementTypes.uint32 = 'uint32_t' 行建议您这样做),那么您可以使用 SIL 执行您所提议的操作,只需几行代码:

    cfg.VerificationMode = 'SIL';
    
    thisStruct.bank_rad = 2.1;
    thisStruct.heading_rad = 3.1;
    thisStruct.pitch_rad = 3.1;
    
    codegen ...
    
    % Now test the generated code. This calls your actual generated code
    % and automatically does all of the necessary data conversion. The code
    % is run in a separate process and outputs are returned back
    % to MATLAB
    getRotationMatrix_sil(thisStruct)
    

    更多信息在doc。如果您有测试/脚本已经在执行您的 MATLAB 代码,您可以通过查看 coder.runTestcodegen -test 选项来重用具有 SIL 的测试/脚本。

    【讨论】:

      【解决方案2】:

      啊,你已经很接近解决方案了 :)

      那里有一个小问题。

      当您使用clibgen.generateLibraryDefinition() 时,您必须确保所有类型定义都包含在头文件中。在您的情况下,struct0_T 的定义是在 getRotationMatrix_types.h 文件中的 presnet。

      因此,您必须使用以下命令包含两个标题:

      clibgen.generateLibraryDefinition(["FrameTransformation.h","getRotationMatrix_types.h"],"PackageName","mylib",'Libraries',{'getRotationMatrix.lib'})
      

      现在您必须填写定义文件中所需的其他详细信息。

      完成该步骤后,您可以使用以下命令成功使用界面

      build(definemylib)
      addpath('\\mathworks\home\dramakan\MLAnswers\CLIB_With_Codegen\ToPort\portzingbit\mylib')
      A = clib.mylib.FrameTransformation
      s = clib.mylib.struct0_T
      s.bank_rad =2.1;
      s.heading_rad =3.1;
      s.pitch_rad=3.1;
      A.getRotationMatrix(s)
      

      我可以在 R2021b 中低于输出

          >> A.getRotationMatrix(s)
      
      ans =
      
          9.6100
      

      另外检查您是否可以使用 MATLAB Coder MEX 而不是做所有这些马戏团。您可以使用 MEX 在 MATLAB 中直接调用生成的代码。您可以参考以下文档: https://www.mathworks.com/help/coder/gs/generating-mex-functions-from-matlab-code-at-the-command-line.html

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-07-14
        • 2021-05-13
        • 1970-01-01
        • 2011-09-17
        • 2017-10-04
        • 1970-01-01
        • 2016-03-25
        • 1970-01-01
        相关资源
        最近更新 更多