在 MATLAB 编码器中使用自定义 C 结构

问题描述

我需要在 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,'vector.h');
coder.cstructname(v,'vector','vector.h');

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

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

% initialise vector
v = coder.opaque('create_vector',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 z);
struct vector create_vector(struct point p0,struct point p1);
double calc_length(struct vector u);

解决方法

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

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