I have a native method that has to deliver a byte array to a .NET wrapper. The natove method looks like:
__declspec(dllexport) int WaitForData(unsigned char* pBuffer)
{
return GetData(pBuffer);
}
GetData allocates a memory region using malloc and copies some data (a byte stream) into it. This byte stream was received via a socket connection. The return value is the length of pBuffer.
This method has to be called from .NET. The import declaration looks as follows:
[DllImport("CommunicationProxy.dll")]
public static extern int WaitForData(IntPtr buffer);
[EDIT]
The the P/Invoke Interop Assistant, that dasblinkenlight advised, translates the prototype to the following import signature:
public static extern int WaitForData(System.IntPtr pBuffer)
The result is the same: ptr is 0 after calling the method.
[/EDIT]
Atfer the method was called, the result is extracted:
IntPtr ptr = new IntPtr();
int length = Wrapper.WaitForData(ref ptr);
byte[] buffer = new byte[length];
for(int i = 0;i<length;i++)
{
buffer[i] = System.Runtime.InteropServices.Marshal.ReadByte(ptr, i);
}
Wrapper.FreeMemory(ptr);
The problem is, that the managed variable ptr doesn't contain the value that the native varible pBuffer contains. ptr is always 0 when Wrapper.WaitForData returns although pBuffer pointed to an allocated memory area.
Is there a mistake in the prototype? How does a pointer to a byte array need to be marshalled?
you need to pass a reference to a pointer or 'double pointer' like that
__declspec(dllexport) int WaitForData(unsigned char** pBuffer)
and then change the value of the pointer(because it's passed by value)
*pBuffer = 'something'
other option - return the pointer(then you'll have to handle the int/length some other way)
btw that's why your automatically generated prototype looks like this(doesn't have out, ref modifiers)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With