在 MATLAB coder 中使用自定义 C 结构体

Posted

技术标签:

【中文标题】在 MATLAB coder 中使用自定义 C 结构体【英文标题】:Using custom C structures with MATLAB coder 【发布时间】:2021-05-28 19:57:20 【问题描述】:

我需要在 MATLAB 中初始化和使用自定义 C 结构的帮助。我的目标是使用外部 C 结构和函数编写 MATLAB 代码。生成的具有这些 C 结构的 MATLAB 代码将由 MATLAB Coder 自动转换为 C。我正在关注this example(请参阅标题为“集成使用自定义数据类型的外部代码”的部分),但不幸的是,编码器给了我以下错误:

Non-constant expression or empty matrix.
This expression must be constant because its value determines the size or class of some expression.
Error in ==> calc_length_c Line: 23 Column: 35

我相信我的问题在于coder.cstructnamestructcoder.opaque 的错误使用。要使用 MATLAB Coder(自动)生成 C 代码,我使用以下命令:

codegen calc_length_c -args 0.1, 0.2, 0.3, 1.5, 1.7, 1.9 -report vector.c

MATLAB 代码,文件calc_length_c.m:

function [l] = calc_length_c(p0x, p0y, p0z, p1x, p1y, p1z) %#coder
%CALC_LENGTH Calculates vector length
%   Calculates vector length. Vector is given by two points in Cartesian 3D space.

% include statements
coder.cinclude('vector.h');

% declare custom C datatypes
coder.cstructname(p0, 'point', 'extern', 'HeaderFile', 'vector.h');
coder.cstructname(p1, 'point', 'extern', 'HeaderFile', 'vector.h');
coder.cstructname(v, 'vector', 'extern', 'HeaderFile', 'vector.h');

% initialise points
p0 = struct('x', 0.0, 'y', 0.0, 'z', 0.0);
p1 = struct('x', 0.0, 'y', 0.0, 'z', 0.0);
v  = struct('p0', p0, 'p1', p1);

% initialise points
p0 = coder.ceval('create_point', p0x, p0y, p0z);
p1 = coder.ceval('create_point', p1x, p1y, p1z);

% initialise vector
v = coder.opaque('create_vector', p0, p1);  % <- error occurs here!

% calculate vector length
l = 0.0;
l = coder.opaque('calc_length', v);
end

C代码,文件vector.c:

#include <math.h>
#include "vector.h"

// Creates point in 3D Cartesian space
struct point create_point(double x, double y, double z) 
    
    struct point p;

    p.x = x;
    p.y = y;
    p.z = z;

    return p;


// Creates vector in 3D Cartesian space, defines origin and end points
struct vector create_vector(struct point p0, struct point p1) 

    struct vector v;

    v.p0 = p0;
    v.p1 = p1;

    return v;


// Calculates length of vector in 3D Cartesian space
double calc_length(struct vector v) 
    return sqrt( pow(v.p1.x-v.p0.x, 2.0) +
                 pow(v.p1.y-v.p0.y, 2.0) +
                 pow(v.p1.z-v.p0.z, 2.0) );

C代码,文件vector.h:

// Definition of point in 3D Cartesian space
struct point 
    double x;
    double y;
    double z;
;

// Definition of vector in 3D Cartesian space
struct vector 
    struct point p0;
    struct point p1;
;

// Routine signatures
struct point create_point(double x, double y, double z);
struct vector create_vector(struct point p0, struct point p1);
double calc_length(struct vector u);

【问题讨论】:

【参考方案1】:

如果create_vector 是一个函数,你想用coder.ceval 调用它。函数coder.opaque 可以被认为只用于类型声明。

根据您的代码,您已经将v 预初始化为一个结构并在其上使用了coder.cstructname。因此,只需将 coder.opaque 切换为 coder.ceval,您就可以开展业务了。后面对calc_length的引用也是如此。

【讨论】:

以上是关于在 MATLAB coder 中使用自定义 C 结构体的主要内容,如果未能解决你的问题,请参考以下文章

如何给matlab coder装license

使用 Matlab Coder 将 C 字符数组转换为 Matlab 字符串

MATLAB Coder 函数在 2014a 中未定义

在 Android Studio 中添加 MATLAB CODER 生成的 C

在 MATLAB Coder 中创建用于指定数组大小的常量

使用 Matlab Coder 将 Matlab m 文件转换为 C/C++ 代码,包括 mex 文件 (mxArray)