This question is an extension of this question.
I would like to adapt the wrapper for the two dimensional case. This is my first attempt:
public class EmxArrayRealTWrapper : IDisposable
{
private readonly emxArray_real_T _value;
private GCHandle _dataHandle;
private GCHandle _sizeHandle;
public emxArray_real_T Value
{
get { return _value; }
}
public EmxArrayRealTWrapper(double[,] data)
{
_dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned);
_value.data = _dataHandle.AddrOfPinnedObject();
_sizeHandle = GCHandle.Alloc(new int[] { data.GetLength(0), data.GetLength(1) }, GCHandleType.Pinned);
_value.size = _sizeHandle.AddrOfPinnedObject();
_value.allocatedSize = data.GetLength(0) * data.GetLength(1) * sizeof(double);
_value.numDimensions = 2;
_value.canFreeData = false;
}
public void Dispose()
{
_dataHandle.Free();
_sizeHandle.Free();
GC.SuppressFinalize(this);
}
~EmxArrayRealTWrapper()
{
Dispose();
}
}
[StructLayout(LayoutKind.Sequential)]
public struct emxArray_real_T
{
public IntPtr data;
public IntPtr size;
public int allocatedSize;
public int numDimensions;
[MarshalAs(UnmanagedType.U1)]
public bool canFreeData;
}
PS:
The orginal matlab code looks like this:
function [x] = test(a)
%#codegen
x = 0;
if(~isempty(coder.target))
assert(isa(a,'double'));
assert(all(size(a) == [1 Inf]));
end
x = sum(a);
and can be invoked like this:
a = [ 1 2; 3 4]
r = test(a)
producing:
r =
4 6
Unfortunately the produced C cannot achieve what Matlab can achieve (i.e. return an array):
__declspec(dllexport) real_T test(const emxArray_real_T *a);
real_T test(const emxArray_real_T *a)
{
real_T x;
int32_T k;
if (a->size[1] == 0) {
x = 0.0;
} else {
x = a->data[0];
for (k = 2; k <= a->size[1]; k++) {
x += a->data[k - 1];
}
}
return x;
}