1

有一个标准示例说明如何在 C++ 中创建或更改数组并将其用作 WarpControlPoints 中的数组:

/*==========================================================
 * arrayProduct.c - example in MATLAB External Interfaces
 *
 * Multiplies an input scalar (multiplier) 
 * times a 1xN matrix (inMatrix)
 * and outputs a 1xN matrix (outMatrix)
 *
 * The calling syntax is:
 *
 *      outMatrix = arrayProduct(multiplier, inMatrix)
 *
 * This is a MEX-file for MATLAB.
 * Copyright 2007-2012 The MathWorks, Inc.
 *
 *========================================================*/
/* $Revision: 1.1.10.4 $ */

#include "mex.h"

/* The computational routine */
void arrayProduct(double x, double *y, double *z, mwSize n)
{
    mwSize i;
    /* multiply each element y by x */
    for (i=0; i<n; i++) {
        z[i] = x * y[i];
    }
}

/* The gateway function */
void mexFunction( int nlhs, mxArray *plhs[],
                  int nrhs, const mxArray *prhs[])
{
    double multiplier;              /* input scalar */
    double *inMatrix;               /* 1xN input matrix */
    size_t ncols;                   /* size of matrix */
    double *outMatrix;              /* output matrix */

    /* get the value of the scalar input  */
    multiplier = mxGetScalar(prhs[0]);

    /* create a pointer to the real data in the input matrix  */
    inMatrix = mxGetPr(prhs[1]);

    /* get dimensions of the input matrix */
    ncols = mxGetN(prhs[1]);

    /* create the output matrix */
    plhs[0] = mxCreateDoubleMatrix(1,(mwSize)ncols,mxREAL);

    /* get a pointer to the real data in the output matrix */
    outMatrix = mxGetPr(plhs[0]);

    /* call the computational routine */
    arrayProduct(multiplier,inMatrix,outMatrix,(mwSize)ncols);
}

这基本上就是我要找的,只是我想改变一个二维数组而不是一个简单的数组。我试图创建一个二维数组(4 xn)并更改第 4 行只是为了看看它是否有效。如果我更改以下几行:

/* The computational routine */
void arrayProduct(double x, double *y, double *z, mwSize n)
{
mwSize i;
/* multiply each element y by x */
for (i=0; i<n; i++) {
z[3][i] = x * y[i];
}
}

/* create the output matrix */
    plhs[0] = mxCreateDoubleMatrix(4,(mwSize)ncols,mxREAL);

它不起作用。我得到的错误z既不是字段也不是指针。谁能告诉我我做错了什么以及我是如何做到这一点的?

4

3 回答 3

3

多维数组仍然存储为单个连续数组,而不是二维 C 数组。数据按列优先顺序,这意味着 z[0] 是元素 (1,1),z[1] 是元素 (2,1),依此类推,一直到 z[4*N-1]

要从所需的 2D 索引(行、列)(从 0 开始)计算线性索引,只需编写idx = column*nrows + row;. 这意味着您需要将 nrows 值传递给您的计算函数。

所以:在你的计算函数中添加一个额外的参数,叫做nrows,并在你调用它时传递这个值。并将 z 索引为一维数组,如上所述。

于 2013-08-29T16:09:34.203 回答
2

提问者可能已经得到了答案。但是,这个答案可能对像我这样从 MATLAB 转向 C++ 并希望在 C++ 中使用一些 MATLAB 功能的人有用。

从 C++ 向 MATLAB 发送一维数组非常简单,因为网上有许多示例可以向您展示该过程。但是将二维数组发送到 MATLAB 有点棘手,因为没有足够的信息可用(尤其是使用动态数组)。下面的代码中显示了一个过程。该过程遵循一些简单的步骤,

  1. 在 C++ 中创建一个二维数组。
  2. engPutVariable_func()使用(用户定义的函数)将该二维数组的每一列发送到 MATLAB 。
  3. engEvalString()使用C++在 MATLAB 中将每一列附加在一起。
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <cmath>
#include <string.h>
#include "engine.h"
#include "mex.h"
#include <armadillo> 
/* I'm using armadillo for convenient matrix operations
 * The process is applicable for other Linear Algebra libraries as well (including STL)
*/

using namespace std;
using namespace arma;

int Create_2DArray_in_Matlab(Engine &m_pEngine, dmat PlotData);
int engPutVariable_func(Engine &m_pEngine, dvec TheVector, string MatVarName);


int main(void)
{
    dmat PlotData(100000, 10, fill::randu);
    /* Our Objective is to Put Matrix "PlotData" in MATLAB workspace*/


    /* Opening Matlab Engine */

    Engine *m_pEngine;
    m_pEngine = engOpen(NULL);
    if (m_pEngine == NULL)
    {
        std::cout << "Error" << std::endl;
        exit(1);
    }
    engSetVisible(m_pEngine, 1);

    engEvalString(m_pEngine, "clc;");
    engEvalString(m_pEngine, "close all;");
    engEvalString(m_pEngine, "clear all;");


    Create_2DArray_in_Matlab(*m_pEngine, PlotData);
    engEvalString(m_pEngine, "open PlotData");

    return 0;

}

int Create_2DArray_in_Matlab(Engine &m_pEngine, dmat PlotData)
{
    /*Approach is to put one column at a time, of a 2D Matrix 
     *in Matlab workspace*/

    int SIZE_Dmat_rows = PlotData.n_rows;
    int SIZE_Dmat_cols = PlotData.n_cols;

    for (int i = 0; i < SIZE_Dmat_cols; i++)
    {
        dvec Temp_Col = PlotData.col(i);
        dvec Col_Number(1); Col_Number(0) = i;
        engPutVariable_func(m_pEngine, Temp_Col, "Temp_Col");
        engPutVariable_func(m_pEngine, Col_Number, "Col_Number");

        engEvalString(&m_pEngine, "PlotData(:, Col_Number + 1) = Temp_Col;");


    }
    return 0;
}


int engPutVariable_func(Engine &m_pEngine, dvec TheVector, string MatVarName)
{
    /*This function will put a column vector in MATLAB Workspace*/

    int SIZE = TheVector.n_rows;

    double *Temp = new double[SIZE];


    for (int i = 0; i < SIZE; i++)
    {
        Temp[i] = TheVector(i);
    }

    char Char_VariableName[1000];
    strcpy(Char_VariableName, MatVarName.c_str());

    /* Creating Matlab Variables*/

    mxArray *TheMatVec = NULL;
    TheMatVec = mxCreateDoubleMatrix(SIZE, 1, mxREAL);
    memcpy((void *)mxGetPr(TheMatVec), (void *)Temp, sizeof(Temp)*SIZE);
    engPutVariable(&m_pEngine, Char_VariableName, TheMatVec);

    delete[] Temp;

    return 0;

}


在一个简单的 MATLAB 程序中,这就是我们在 C++ 中所做的

clc
clear all
close all

A = rand(10, 20); 

for i = 1:length(A)
    A_Temp = A(:, i);
    B(:, i) = A_Temp
    A_Temp = [];
end

希望这些信息可能有用...

如有任何疑问和批评,请发表评论。

谢谢并恭祝安康

于 2019-06-25T14:26:23.357 回答
1

从根本上说,二维数组总是需要定义它的第一维。

将指针 (z) 视为 2d 数组打破了该规则。

如果没有定义第一个维度(实际上是除最后一个维度之外的所有维度),则无法正确计算与指针的实际偏移量。

在您的代码中,您知道每个维度的大小是相等的,您可以自己计算指针偏移量。

于 2013-08-29T16:07:14.650 回答