C # Call the C/C ++ dynamic library to send struct, struct array,
I.Transfer of struct
Cpp Code
# Define JNAAPI extern "C" _ declspec (dllexport) // The typedef struct {int osVersion; int majorVersion; int minorVersion; int buildNum; int platFormId; char szVersion [128];} OSINFO; // 1. get version information (pass struct pointer) JNAAPI bool GetVersionPtr (OSINFO * info); // 2. get version information (pass struct reference) JNAAPI bool GetVersionRef (OSINFO & info );
C # code
// OSINFO defines [StructLayout (LayoutKind. sequential)] public struct OSINFO {public int osVersion; public int majorVersion; public int minorVersion; public int buildNum; public int platFormId; [financialas (UnmanagedType. byValTStr, SizeConst = 128)] public string szVersion ;}
You can call the following two methods:
1. method 1Struct referenceIn C #, the struct is passed by passing the value, and the class is passed by passing the address. Add the keyword ref. two different types of parameters are passed on the C-end, which can be solved through reference.
C # code
[DllImport("jnalib.dll", EntryPoint = "GetVersionPtr")] public static extern bool GetVersionPtr(ref OSINFO info); public static extern bool GetVersionRef(ref OSINFO info);
2. method 2 (Input IntPtr(Universal platform pointer ))
C # code
IntPtr pv = Marshal. allocHGlobal (148); // The struct must allocate space (4 * sizeof (int) + 128) when using it. writeInt32 (pv, 148); // write the value if (GetVersionPtr (pv) to the memory block. // directly use the unhosted memory block address as the parameter {Console. writeLine ("-- osVersion: {0}", Marshal. readInt32 (pv, 0); Console. writeLine ("-- Major: {0}", Marshal. readInt32 (pv, 4); // move 4 bytes of Console. writeLine ("-- BuildNum:" + Marshal. readInt32 (pv, 12); Console. writeLine ("-- szVersion:" + Marshal. ptrToStringAnsi (IntPtr) (pv. toInt32 () + 20);} Marshal. freeHGlobal (pv); // release the memory after processing
II.Transfer of struct Arrays
Cpp Code
// Pass the struct pointer JNAAPI bool GetVersionArray (OSINFO * info, int nLen );
Call code:
C # code
/*** C # interface. Only IntPtr */[DllImport ("jnalib. dll ", EntryPoint =" GetVersionArray ")] public static extern bool GetVersionArray (IntPtr p, int nLen); // source target parameter OSINFO [] infos = new OSINFO [2]; for (int I = 0; I <infos. length; I ++) {infos [I] = new OSINFO ();} IntPtr [] ptArr = new IntPtr [1]; ptArr [0] = Marshal. allocHGlobal (Marshal. sizeOf (typeof (OSINFO) * 2); // allocate an array containing two elements IntPtr pt = Marshal. allocHGlobal (Marshal. sizeOf (typeof (OSINFO); Marshal. copy (ptArr, 0, pt, 1); // Copy the pointer array GetVersionArray (pt, 2); // call // restore to a struct array for (int I = 0; I <2; I ++) {infos [I] = (OSINFO) Marshal. ptrToStructure (IntPtr) (pt. toInt32 () + I * Marshal. sizeOf (typeof (OSINFO), typeof (OSINFO); Console. writeLine ("OsVersion: {0} szVersion: {1}", infos [I]. osVersion, infos [I]. szVersion );}
III.Transfer of complex struct
1. output parameters. The struct is used as the pointer to output data.
Cpp Code
Typedef struct {char name [20]; int age; double scores [30];} Student; // Class contains the struct array type typedef struct {int number; student students [50];} Class; // pass in the complex struct test JNAAPI int GetClass (Class * pClass, int len );
C # code
// Interface Definition [DllImport ("jnalib. dll ", EntryPoint =" GetClass ")] public static extern int GetClass (IntPtr pv, int len); // struct definition // Student [StructLayout (LayoutKind. sequential)] public struct Student {[financialas (UnmanagedType. byValTStr, SizeConst = 20)] public string name; public int age; [financialas (UnmanagedType. byValArray, SizeConst = 30)] public double [] scores;} // Class [StructLayout (LayoutKind. sequential)] public struct Class {public int number; [financialas (UnmanagedType. byValArray, SizeConst = 50)] // specify the array size public Student [] students; // struct array definition} // call the complex struct test int size = Marshal. sizeOf (typeof (Class) * 50; IntPtr pBuff = Marshal. allocHGlobal (size); // directly allocate space for 50 elements, such as Marshal. copy facilitates the addition of GetClass (pBuff, 50); Class [] pClass = new Class [50]; for (int I = 0; I <50; I ++) {IntPtr ptr = new IntPtr (pBuff. toInt64 () + Marshal. sizeOf (typeof (Class) * I); pClass [I] = (Class) Marshal. ptrToStructure (ptr, typeof (Class);} Marshal. freeHGlobal (pBuff); // release memory
2. input parameters. assign values to the complex struct and pass them as input parameters.
For large struct pointers, you cannot directly apply the struct type to the IntPtr type. In this case, you need to convert the native type to the pointer and assign a value to the pointer.
Call method:
Marshal.StructureToPtr(stu, ptr1, true)
Go to excerpt
C # Call the C/C ++ dynamic library to send struct, struct Array