How can I access a structure in csharp containing dynamic arrays from an unmanaged DLL?

- In my c-code, I have a structure that contains many unknown arrays in an unmanaged dll (c-code)

- I need the data of one instance of this structure, bound to C # , which I will later send back to unmanaged code c

- I do not need to manipulate this data when it gets into csharp, just hold it / keep it for a while (so that it can remain in an array of bytes).

-I donโ€™t want to use the keyword โ€œunsafeโ€, because this is a large project, and this is just one small part, and I do not want to compile such files.

I tried marshaling it as lpArray and everything looks fine, but when I look at the contents after returning to csharp, it is always empty. This type of marshaling style worked for me for dynamic arrays of various types, but not for structure.

A search on the Internet is a workpiece and much more complex scripts than my own, but if anyone saw such a link, send it here, I would be very grateful!

Thanks.

- update here more or less the structure of my code:

FROM#:

[DllImport("mydll.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] private static extern int W_Thread_Connect_NET( [MarshalAs(UnmanagedType.LPStr, SizeConst = 100)] string IPAddress, int DevicePort, [MarshalAs(UnmanagedType.LPArray)] byte[] connectionHandle ); //and call it like this, with an empty struc to be populated by c (can this be done? it is comming back without the data): byte[] myStrucParam= new byte[100]; int result = W_Thread_Connect_NET(myStrucParam, myParam1, myParam2, ...); 

from:

  typedef struct myStructDef{ char* myArray1, char* myArray2, int myInt1, ... } mystrucObj, *pMystrucObj; //method that i am wanting to marshal the struct as a paramter here.. MYDLL_DLLIMPORT int APIENTRY W_Thread_Connect_NET(pMystrucObj strucReturn_handle, char * IPAddress, int DevicePort, ...) { //(omitted) } 
+4
source share
1 answer

You say that C # code does not need to manipulate the structure. This makes it a pretty simple problem. You can treat the struct pointer as an opaque pointer, that is, IntPtr .

First of all, you add a new function to your own code:

 pMystrucObj CreateStruct(void) { pMystrucObj res = malloc(sizeof(*res)); return res; } 

Then in C # code you call it like this:

 [DllImport("mydll.dll", CallingConvention=CallingConvention.Cdecl)] private static extern IntPtr CreateStruct(); 

Now declare W_Thread_Connect_NET as follows:

 [DllImport("mydll.dll", CallingConvention=CallingConvention.Cdecl)] private static extern int W_Thread_Connect_NET( IntPtr theStructPtr, string IPAddress, int DevicePort, .... ); 

And call it that:

 IntPtr theStructPtr = CreateStruct(); int res = W_Thread_Connect_NET(theStructPtr, IPAddress, DevicePort, ...); 

And, of course, you'll want to add another function called DestroyStruct to free the memory of the structure as soon as you finish with it.

+2
source

Source: https://habr.com/ru/post/1403237/


All Articles