C # Call the C/C ++ dynamic library to send struct, struct Array

Source: Internet
Author: User
Tags array definition

Because the company has always been engaged in C ++ development, because the customer needs to provide the C # version interface, I studied C # and found that it is powerful and concise, it is completely encapsulated in cross-language calls and provides powerful API interaction. this is much more convenient than JNA. both Java and C # can only call the C format to export the dynamic library, because C has a single data type and is easy to map. both of them provide a set of ing C #/java description interfaces on the local end, which can be called through the underlying processing of this ing relationship.

 

I.Transfer of struct

 

Cpp Code
  1. # Define JNAAPI extern "C" _ declspec (dllexport) // export functions in C mode
  2. Typedef struct
  3. {
  4. Int osVersion;
  5. Int majorVersion;
  6. Int minorVersion;
  7. Int buildNum;
  8. Int platFormId;
  9. Char szVersion [128];
  10. } OSINFO;
  11. // 1. Get version information (passing the struct pointer)
  12. JNAAPI bool GetVersionPtr (OSINFO * info );
  13. // 2. Get version information (Transfer struct reference)
  14. JNAAPI bool GetVersionRef (OSINFO & info );

 

 

You can call the following two methods:

 

C # code
  1. // OSINFO Definition
  2. [StructLayout (LayoutKind. Sequential)]
  3. Public struct OSINFO
  4. {
  5. Public int osVersion;
  6. Public int majorVersion;
  7. Public int minorVersion;
  8. Public int buildNum;
  9. Public int platFormId;
  10. [Financialas (UnmanagedType. ByValTStr, SizeConst = 128)]
  11. Public string szVersion;
  12. }

 

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
  1. [DllImport ("jnalib. dll", EntryPoint = "GetVersionPtr")]
  2. Public static extern bool GetVersionPtr (ref OSINFO info );
  3. Public static extern bool GetVersionRef (ref OSINFO info );

 

2. method 2 (Input IntPtr(Universal platform pointer ))

 

Cpp Code
  1. IntPtr pv = Marshal. AllocHGlobal (148); // The struct must be allocated space (4 * sizeof (int) + 128) during use)
  2. Marshal. WriteInt32 (pv, 148); // write a value to the memory block
  3. If (GetVersionPtr (pv) // directly takes the unhosted memory block address as the parameter
  4. {
  5. Console. WriteLine ("-- osVersion: {0}", Marshal. ReadInt32 (pv, 0 ));
  6. Console. WriteLine ("-- Major: {0}", Marshal. ReadInt32 (pv, 4); // move 4 bytes
  7. Console. WriteLine ("-- BuildNum:" + Marshal. ReadInt32 (pv, 12 ));
  8. Console. WriteLine ("-- szVersion:" + Marshal. PtrToStringAnsi (IntPtr) (pv. ToInt32 () + 20 )));
  9. }
  10. Marshal. FreeHGlobal (pv); // after processing, remember to release the memory.

 

 

II.Transfer of struct Arrays

 

Cpp Code
  1. // Pass the struct pointer
  2. JNAAPI bool GetVersionArray (OSINFO * info, int nLen );

Call code:

 

C # code
  1. /**
  2. * C # interface. For an array type, only IntPtr can be passed.
  3. */
  4. [DllImport ("jnalib. dll", EntryPoint = "GetVersionArray")]
  5. Public static extern bool GetVersionArray (IntPtr p, int nLen );
  6. // Source target parameter
  7. OSINFO [] infos = new OSINFO [2];
  8. For (int I = 0; I <infos. Length; I ++)
  9. {
  10. Infos [I] = new OSINFO ();
  11. }
  12. IntPtr [] ptArr = new IntPtr [1];
  13. PtArr [0] = Marshal. AllocHGlobal (Marshal. SizeOf (typeof (OSINFO) * 2); // assign an array containing two elements
  14. IntPtr pt = Marshal. AllocHGlobal (Marshal. SizeOf (typeof (OSINFO )));
  15. Marshal. Copy (ptArr, 0, pt, 1); // Copy the pointer Array
  16. GetVersionArray (pt, 2); // call
  17. // Restore to a struct Array
  18. For (int I = 0; I <2; I ++)
  19. {
  20. Infos [I] = (OSINFO) Marshal. ptrToStructure (IntPtr) (pt. toInt32 () + I * Marshal. sizeOf (typeof (OSINFO), typeof (OSINFO ));
  21. Console. WriteLine ("OsVersion: {0} szVersion: {1}", infos [I]. osVersion, infos [I]. szVersion );
  22. }

 

 

III.Transfer of complex struct

 

1. output parameters. The struct is used as the pointer to output data.

Cpp Code
  1. Typedef struct
  2. {
  3. Char name [20];
  4. Int age;
  5. Double scores [30];
  6. } Student;
  7. // Class contains the struct array type
  8. Typedef struct
  9. {
  10. Int number;
  11. Student students [50];
  12. } Class;
  13. // Pass in complex struct Test
  14. JNAAPI int GetClass (Class * pClass, int len );

 

Cpp Code
  1. // Interface Definition
  2. [DllImport ("jnalib. dll", EntryPoint = "GetClass")]
  3. Public static extern int GetClass (IntPtr pv, int len );
  4. // Struct Definition
  5. // Student
  6. [StructLayout (LayoutKind. Sequential)]
  7. Public struct Student
  8. {
  9. [Financialas (UnmanagedType. ByValTStr, SizeConst = 20)]
  10. Public string name;
  11. Public int age;
  12. [Financialas (UnmanagedType. ByValArray, SizeConst = 30)]
  13. Public double [] scores;
  14. }
  15. // Class
  16. [StructLayout (LayoutKind. Sequential)]
  17. Public struct Class
  18. {
  19. Public int number;
  20. [Financialas (UnmanagedType. ByValArray, SizeConst = 50)] // specify the array size
  21. Public Student [] students; // struct array Definition
  22. }
  23. // Call the complex struct Test
  24. Int size = Marshal. SizeOf (typeof (Class) * 50;
  25. IntPtr pBuff = Marshal. AllocHGlobal (size); // directly allocate space for 50 elements, which is much easier than Marshal. copy.
  26. GetClass (pBuff, 50 );
  27. Class [] pClass = new Class [50];
  28. For (int I = 0; I <50; I ++)
  29. {
  30. IntPtr ptr = new IntPtr (pBuff. ToInt64 () + Marshal. SizeOf (typeof (Class) * I );
  31. PClass [I] = (Class) Marshal. PtrToStructure (ptr, typeof (Class ));
  32. }
  33. Marshal. FreeHGlobal (pBuff); // release the 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)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.