我假设 MATLAB 数组结构使用 col-major 排序。在这种情况下,结构体构造函数需要如下所示:
public EmxArrayRealTWrapper(double[,] data)
{
int nRow = data.GetLength(0);
int nCol = data.GetLength(1);
double[] flattenedData = new double[nCol * nRow];
int index = 0;
for (int col=0; col<nCol; col++)
{
for (int row=0; row<nRow; row++)
{
flattenedData[index] = data[row, col];
index++;
}
}
_dataHandle = GCHandle.Alloc(flattenedData, GCHandleType.Pinned);
_value.data = _dataHandle.AddrOfPinnedObject();
_sizeHandle = GCHandle.Alloc(new int[] { nCol, nRow }, GCHandleType.Pinned);
_value.size = _sizeHandle.AddrOfPinnedObject();
_value.allocatedSize = nCol * nRow;
_value.numDimensions = 2;
_value.canFreeData = false;
}
如果本机代码需要行优先,那么它会更简单。 C# 多维数组存储为连续的行优先数组。因此,您可以使用与我在最近的问题中提供的一维代码非常相似的代码。
public EmxArrayRealTWrapper(double[,] data)
{
int nRow = data.GetLength(0);
int nCol = data.GetLength(1);
_dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned);
_value.data = _dataHandle.AddrOfPinnedObject();
_sizeHandle = GCHandle.Alloc(new int[] { nRow, nCol }, GCHandleType.Pinned);
_value.size = _sizeHandle.AddrOfPinnedObject();
_value.allocatedSize = nCol * nRow;
_value.numDimensions = 2;
_value.canFreeData = false;
}
请注意,这两种变体将数据传递给本机代码的方式有所不同。第一个版本传递原始数据的副本。第二个传递对原始数据的引用。我不确定你希望你的代码如何表现。修改第二个版本来传递副本很容易。对于第一个版本,如果您希望本机代码修改数据并将这些修改反映回托管代码,那么您需要在本机调用返回后将修改封送回来。