我试图在Matlab中调用C ++中的函数,我以为我已经正确地编写了我的函数。我想调用的函数看起来像这样,它有8个参数作为输入。
void LimitedPrice(double &dMarketPosition, double** dmatLimitPrice,
char* FileID, double* dvecOpen, double* dvecClose,
double** dmatTempData, int tick, double dMaxBarBack)
{Bla, Bla, Bla}
我希望在运行此功能后获得2个值。其中存储在dMarketPosition和dmatLimitPrice中,因为它们是指针。
在这个函数中,我必须使用一些**(双指针)来表示我的Matrix。
运行此功能后, dMarketPosition,dmatLimitPrice 将存储我想要的内容,因为它们是指针。我测试了我的功能,我相信我的功能写得很好。
现在我准备好编写 mexFunction()了。 我的mex功能看起来像这样
void mexFunction(int nlhs, mxArray *plhs[],
int nrhs,const mxArray *prhs[])
{
if(nrhs!=8){
mexErrMsgIdAndTxt("LimitPrice: ","I want to 8 inputs");
}
// I want two output
if(nlhs!=2) {
mexErrMsgIdAndTxt("LimitPrice: ","I want to 2 outputs");
}
//The first input is a scalar
double dmarketposition;
dmarketposition = mxGetScalar(prhs[0]);
//The second input is a 2-dimensional Matrix
double **dmatlimitprice;
*dmatlimitprice = mxGetPr(prhs[1]);
/*****Assuming I have checked other inputs here properly*****/
// I want to define my outputs
// Create 1*1 matrix as output, which is the double value I want
plhs[0] = mxCreateDoubleMatrix(1,1,mxREAL);
//The second output is a two dimensional matrix
plhs[1] = mxCreateDoubleMatrix(2,(mwSize)4,mxREAL);
dmarketposition = mxGetScalar(plhs[0]);
*dmatlimitprice = mxGetPr(plhs[0]);
// Call the function
LimitedPrice(dmarketposition, dmatlimitprice, fileid,
dvecopen, dvecclose, dmattempdata, tick, dmaxbarback);
}
以上功能似乎不起作用......似乎在mexFunction()中, 我们最好只传递一维数组,这是一个双倍的东西。
我的关键问题是“我们如何处理二维数组,这是mexFunction()中的矩阵”。
答案 0 :(得分:2)
在内存中,Matlab将所有mxArray
列作为一列连续内存逐列存储。在这方面,1D向量和N-D阵列之间没有区别,它们都存储为单个内存块。
例如,考虑内存中的以下块:{ 1, 2, 3, 4, 5, 6, 7, 8 }
它可以被视为1×8,8×1,2×4,4×2或甚至2×2×2阵列。更改数组的shape
(reshape
- ing)不需要更改存储数据的实际内存,只需更改mxArray
的“标题”。
您可以做的是在内部分配2D矩阵,调用LimitedPrice
,然后将结果复制到输出mxArray
,将其从内部double**
表示转换为double*
mxArray
代表。
附注,在您的示例代码中,您分配dmarketposition
和dmatlimitprice
两次:一次来自第一个和第二个输入,一次来自新分配的输出 - 第二个分配只是覆盖第一个和它看起来您的函数LimitedPrice
无法获取存储在mexFunction
输入中的信息。
答案 1 :(得分:1)
制作数组2D(或除1D以外的任何大小)的唯一因素是存储在mxArray
结构中的数组的形状。所有数据都是连续的。 MATLAB(和mxArray
s)中2D数组的步幅或列间字节数始终为number_of_rows * element_size
。对于列主存储系统,这是一种说明连续数据缓冲区用于存储所有数组的方式。
从mxArray
:
double* mxGetPr(const mxArray*); // get pointer to start of double buffer
void* mxGetData(const mxArray*); // get pointer to start of any data-type buffer
size_t mxGetM(const mxArray*); // get number of rows
size_t mxGetN(const mxArray*); // get number of columns
没有像OpenCV's T* ptr<T>(int i)
这样的函数来获取指向指定行(或MATLAB中的列)的指针。要获取元素,您只需访问位置irow + icol*numRows
即可。这就是为什么在C / C ++中有一个类似sub2ind
的函数的常见原因:
inline mwSize sub2ind(mwSize irow, mwSize icol, mwSize numRows) {
return irow + icol*numRows; }
这是通用建议,没有特定于您的代码。由于LimitedPrice()
的语义不明确,我对提出具体建议犹豫不决。语法很明确 - 它需要指向指针的指针 - 但通常使用**
来返回新指针(内部分配的结果)而不是管理2D数组。如果它的2D数据通常会有两个整数类型来指定尺寸,但我不会看到它。
由于上述原因,很难提供更具体的帮助,但这里有一个很大的问题需要解决:
double **dmatlimitprice;
*dmatlimitprice = mxGetPr(prhs[1]); // dereferencing uninitialized pointer, ERROR
你可以创建一个double**
作为输入矩阵列的索引(如果这是你真正需要的那些!)。例如:
size_t numCols = mxGetN(prhs[1]);
double *dlimitBuffer = mxGetPr(prhs[1]);
// Simulate a 2D array:
std::vector<double*> dlimitvec(numCols);
double **dmatlimitprice = &dlimitvec[0]; // or = new double*[numCols]; if you delete[]
for (size_t i=0; i < numCols; ++i)
datalimitprice[i] = dlimitBuffer + i*numRows;
假设您需要double**
,其中每个double*
指向某个矩阵的各列,这可能不正确,因此请将此视为示例。您也可能需要转置矩阵。
此外,您对*dmatlimitprice
进行了两次无效分配,因此很难判断您是否希望将其作为输入或输出数组。