_msize() on managed data arrays?
-
There is a native function wich takes arrays of pointers to data arrays e.g.
char
allocated with malloc.void function(char** data, int nRows)
{
for (int i = 0; i < nRows; i++)
{
int nCols = _msize(data[i]);
for (j = 0; j < nCols; j++)
char val = data[i][j];
}
}In managed code I have enumeration of
byte[]
arrays to pass to that function via PInvokeunsafe void MyFunction(IEnumerable data)
{
var handles = data.Select(d => GCHandle.Alloc(d, GCHandleType.Pinned));
var ptrs = handles.Select(h => h.AddrOfPinnedObject());
IntPtr[] dataPtrs = ptrs.ToArray();
uint nRows = (uint)dataPtrs.Length;function(dataPtrs, nRows);
handles.ToList().ForEach(h => h.Free());
}[DllImport("function.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
static extern unsafe internal void function(IntPtr[] data, uint nRows);However _msize call in native code leads to heap corruption. I remeber I used stackalloc with one dimensional array char* and concatenated byte[] arrays together. But I need support for 'jagged array' with individual byte[] arrays of different sizes hence the need for array of pointers char**. How to pin the byte[] arrays so that _msize correctly works as in stackalloc case?
Чесноков
-
There is a native function wich takes arrays of pointers to data arrays e.g.
char
allocated with malloc.void function(char** data, int nRows)
{
for (int i = 0; i < nRows; i++)
{
int nCols = _msize(data[i]);
for (j = 0; j < nCols; j++)
char val = data[i][j];
}
}In managed code I have enumeration of
byte[]
arrays to pass to that function via PInvokeunsafe void MyFunction(IEnumerable data)
{
var handles = data.Select(d => GCHandle.Alloc(d, GCHandleType.Pinned));
var ptrs = handles.Select(h => h.AddrOfPinnedObject());
IntPtr[] dataPtrs = ptrs.ToArray();
uint nRows = (uint)dataPtrs.Length;function(dataPtrs, nRows);
handles.ToList().ForEach(h => h.Free());
}[DllImport("function.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
static extern unsafe internal void function(IntPtr[] data, uint nRows);However _msize call in native code leads to heap corruption. I remeber I used stackalloc with one dimensional array char* and concatenated byte[] arrays together. But I need support for 'jagged array' with individual byte[] arrays of different sizes hence the need for array of pointers char**. How to pin the byte[] arrays so that _msize correctly works as in stackalloc case?
Чесноков
Hello. Looking at the documentation for _msize function, it says that it returns the length of a memory block allocated by calloc, malloc or realloc so, since your byte[] arrays are allocated into the managed heap, I think it will not work unless you use Marshal.AllocHGlobal (and I am not sure if this would work) to allocate the memory and then copy data from managed heap to unmanaged heap and viceversa. stackalloc could be used for one dimensional arrays becouse it is very similar to C _alloca function but, as far as I know, it is not possible in other cases, becouse stackalloc keyword can only be used when declaring and initializing a variable, I mean:
byte* pt = stackalloc byte[100]; // this is fine
byte* pt2;
pt2 = stackalloc byte[100]; // this does not work