【问题标题】:Working with preallocated arrays in Matlab's mex function在 Matlab mex 函数中使用预分配的数组
【发布时间】:2012-03-23 19:06:36
【问题描述】:

我写了一个简单的 mex 函数,它更新了 Matlab 数组已经分配的内容:

mex_test_array.c

#include "mex.h"

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    double *x = mxGetPr(prhs[0]);
    x[0] = 3.1416;
}

测试 1:

>> y = zeros(2, 2);
>> mex_test_array(y);
>> y

y =

    3.1416         0
         0         0

测试 2:

>> y = zeros(2, 2);
>> mex_test_array(y(:, 1));
>> y

y =

     0     0
     0     0

为什么它不适用于子矩阵(测试 2)?有没有可能让它发挥作用?

请指教。

备注: 我知道,更新输入数组并不是预期的 mex 文件的写入方式,而且我知道如何从 mex 返回数组。 我尝试这种技术的原因是避免两次分配数组的内存。

【问题讨论】:

    标签: matlab mex


    【解决方案1】:

    不应该工作,因为MATLAB 不希望“右手边的参数”改变。例如见the online help:

    prhs [is an] 指向输入数据的指针数组。输入数据是只读的,并且 不应被您的 mexFunction 更改。

    这就是为什么你的函数头

    void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
    

    const mxArray *prhs[] 而不是mxArray *prhs[]。如果您想返回一个值,您应该通过mxArray *plhs[] 执行此操作。我认为更改“右侧参数”时的行为尚未定义,建议阅读完整的MEX files guide 以了解更多详细信息。

    更新

    为了回答您的实际问题,我假设当您将 y 交给您的函数时,MATLAB 会将实际指针交给您,并且(错误地)相信您不会弄乱它;当您将函数 y(:,1) 交给函数时,MATLAB 会复制数组的该部分并交给您一个指向该副本的指针,该指针在您的函数调用后被丢弃。

    如果您坚持这样做,请至少阅读 Undocumented Matlab 上的 Matlab mex in-place editing,正如 reve_etrange 在 cmets 中指出的那样!本质上,您必须运行

    mxUnshareArray(const_cast<mxarray *>(prhs[0]), true); 
    

    在修改该数组之前。否则运行

    >> y = zeros(2, 2);
    >> y_backup=y;
    >> mex_test_array(y);
    

    会导致

    >> y    
    y =    
        3.1416         0
                 0         0
    >> y_backup
    y =    
        3.1416         0
                 0         0
    

    ...这会导致一些无法维护的地狱般的代码!

    【讨论】:

    • 但是,有 undocumented internal functions 允许您“就地”在 mxArrays 上操作。
    • 乔纳斯,我在我的问题中添加了评论(我知道这不是非常规的方式)。从你的回答“当你把你的函数 y(:,1) MATLAB 复制了数组的那部分”我假设没有什么可做的允许传递 mex 一个指向实际 y(:,1) 的指针?
    猜你喜欢
    • 1970-01-01
    • 2012-06-28
    • 2011-09-07
    • 1970-01-01
    • 1970-01-01
    • 2013-11-17
    • 1970-01-01
    • 2013-08-19
    • 1970-01-01
    相关资源
    最近更新 更多