I have problems with marshalling output parameter of c++ function returning array of data to c#.
Here is C++ declaration:
#define DLL_API __declspec(dllexport)
typedef TPARAMETER_DATA
{
char *parameter;
int size;
} PARAMETER_DATA;
int DLL_API GetParameters(PARAMETER_DATA *outputData);
The function allocates memory for char array, places the data there and returns the number of allocated bytes in “size” field.
Here is my c# declaration:
[StructLayout(LayoutKind.Sequential)]
public struct PARAMETER_DATA
{
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.I1, SizeConst = 50000)]
public byte[] data; // tried also SizeParamIndex = 1 instead of SizeConst
[MarshalAs(UnmanagedType.I4)]
public int size;
}
[DllImport("thedll.dll", SetLastError = true, ExactSpelling = true)]
public extern static uint GetParameters(ref PARAMETER_DATA outputData); // tried also 'out' parameter
When calling the function in c# I get empty structure (size=0, empty array). I tried passing outputData parameter with data feld initialized to new byte[50000] but no data is returned anyway.
Every other function in this dll (some with complex input structures) are working fine, but this is the only function that allocates memory to return data.
I tried many other C# marshalling declarations (with LPArray, LPString) with no luck – always empty data structure is returned or memory access exception is thrown.
Am I missing something simple here?
EDIT:
I cannot change the c++ code – it’s external library.
The problem you’re facing is that a pointer is returned – not really a string or an array. There is no way for the marshaller to convert the pointer to an array or string, because the length is unknown.
The solution might be to do the pointer handling in c#. You should also figure out if you’re responsible for freeing the pointer, or that the library will do that for you.