I have a class definition as follows:
[StructLayout(LayoutKind.Sequential)]
public class OUR_MEM_STR
{
public byte[] p;
public int len;
};
This is an equivalent defintion of the C structure below:
typedef struct
{
void *p;
int len;
} OUR_MEM_STR;
I used byte[] instead of IntPtr type for member p becuase of the way it was being used thorughout c# project.
I have defined an object obj with len = 10 and p = new byte[10]
I want to make it an intptr. How do I get the size of the object for that?
IntPtr pObj = Marshal.AllocHGlobal(obj.len + sizeof(int));
Marshal.StructureToPtr(obj, pObj, true);
See what I did there. It seems too hard coded. If I do the below snippet;
IntPtr pObj = Marshal.AllocHGlobal(Marshal.SizeOf(obj));
Doing this returns the wrong size because obj.p returns a size of 4 and not 10. Because of the memory taken by the pointer pointing to the byte array is 4 bytes.
Is there a better way?
The return value is correct,
p
is a pointer, it takes 4 bytes.You cannot leave it this way, there are two memory allocations. The marshaller allocated the memory for the array. It created a SAFEARRAY, a COM array type. Pretty unlikely that your C code is going to be happy with that. Declare it like this instead:
And use Marshal.AllocHGlobal(10) to assign
p
. Don't forget to clean-up again.Don't pass true to StructureToPtr(), the memory allocated by AllocHGlobal() isn't initialized. That's going to randomly crash your program. You must pass false.