When using a third-party unmanaged API, we often encounter a pointer with a parameter of pointer or pointer,
Generally, we use IntPtr to point to the parameter address we need to pass;
But how can we use IntPtr correctly when we encounter such an export function,
Extern "C" _ declspec (dllexport) int GetClass (Class pClass [50]);
As this situation may also happen frequently, I have created two sample programs to demonstrate how to handle this kind of unmanaged function call!
First, create a C ++ DLL and set an export function as above.
# Include <Windows. h> # include <stdio. h> typedef struct Student {char name [20]; int age; double scores [32];} Student; typedef struct Class {int number; Student students [126];} Class; extern "C" _ declspec (dllexport) int GetClass (Class pClass [50])
{For (int I = 0; I <50; I ++)
{PClass [I]. number = I; for (int j = 0; j <126; j ++)
{Memset (pClass [I]. students [j]. name, 0, 20); sprintf (pClass [I]. students [j]. name, "name _ % d", I, j); pClass [I]. students [j]. age = j % 2 = 0? 15: 20;} return 0;} The above DLL export function requires that the parameter passed is its custom Class struct array, then we need to customize the corresponding struct when calling C,
We can define it as follows:
[StructLayout (LayoutKind. sequential)] struct Student {[financialas (UnmanagedType. byValTStr, SizeConst = 20)] public string name; public int age; [financialas (UnmanagedType. byValArray, SizeConst = 32)] public double [] scores;} [StructLayout (LayoutKind. sequential)] struct Class {public int number; [financialas (UnmanagedType. byValArray, SizeConst = 126)] public Student [] students;} note that the size of the arrays in these two struct must be the same as the size specified in C ++, next, how can we use this API to obtain data correctly? Most people may think of a method like this.
Class myclass = new Class (); IntPtr = Marshal. allocHGlobal (Marshal. sizeOf (typeof (Class); GetClass (ptr); Marshal. freeHGlobal (ptr); yes, this processing is fine, but our API parameters are Class arrays. This processing method only transmits a Class struct parameter, so this method is not suitable here ,!
Then we thought of first Class [] myclass = new Class [MaxClass]; then we were using objective Al. AllocHGlobal to get the pointer of myclass data,
In fact, this is also wrong, because the Class structure contains a Student structure that cannot be directly enclosed, so the above idea is wrong in any case!
What should we do? In fact, it is very easy to allocate a piece of unmanaged memory and call the API before reading the data of the unmanaged content to the hosted structured data!
DEMO code for sending struct arrays in C language:
1 static void Main (string [] args)
2 {
3 int size = Marshal. SizeOf (typeof (Class) * 50;
4 byte [] bytes = new byte [size];
5 IntPtr pBuff = Marshal. AllocHGlobal (size );
6 Class [] pClass = new Class [50];
7 GetClass (pBuff );
8 for (int I = 0; I <50; I ++)
9 {
10 IntPtr pPonitor = new IntPtr (pBuff. ToInt64 () + Marshal. SizeOf (typeof (Class) * I );
11 pClass [I] = (Class) Marshal. PtrToStructure (pPonitor, typeof (Class ));
12}
13 Marshal. FreeHGlobal (pBuff );
14 Console. ReadLine ();
15} if you are interested, test the C-language mail structure array to see if the output result is correct!
Excerpted from Mai Ling Network