Now the company wants to do a C # program to invoke C + + DLL library, parsing file functionality. So I found some information on the Internet.
I. Transmission of structural body
#define JNAAPI extern "C" __declspec (dllexport)//C mode export function
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. Obtain version information (transitive structure reference)
JNAAPI bool Getversionref (OSINFO &info);
You can invoke it in two ways:
OSINFO definition
[StructLayout (layoutkind.sequential)] public
struct OSINFO
{public
int osversion;
public int majorversion;
public int minorversion;
public int buildnum;
public int platformid;
[MarshalAs (UnmanagedType.ByValTStr, SizeConst = 128)]
public string szversion;
}
1. Mode One (incoming structure reference), in C #, the structure is transmitted in the way of value, the class is to pass the address way, plus the keyword ref can. The C-side passes two different types of parameters, which can be resolved by reference.
[DllImport ("Jnalib.dll", EntryPoint = "getversionptr")]
public static extern bool Getversionptr (ref OSINFO info);
public static extern bool Getversionref (ref OSINFO info);
2. Mode two (incoming IntPtr (Platform universal Pointer))
INTPTR PV = Marshal.allochglobal (148); The structure must be allocated in space (4*sizeof (int) +128)
Marshal.writeint32 (pv,148);//write value to memory block
if (Getversionptr (PV))// directly to the unmanaged memory block address as parameter
{
Console.WriteLine ("--osversion:{0}", Marshal.readint32 (PV, 0));
Console.WriteLine ("--major:{0}", Marshal.readint32 (PV, 4)); Move 4 bytes
Console.WriteLine ("--buildnum:" + Marshal.readint32 (PV,));
Console.WriteLine ("--szversion:" +marshal.ptrtostringansi (INTPTR) (PV. ToInt32 ()) (+20)));
Marshal.freehglobal (PV); Remember to release memory after processing
Two. Transmission of structure Array
The transfer structure body pointer
jnaapi bool Getversionarray (OSINFO *info,int nlen);
Call:
/**
* C # interface, for containing array types, can only be passed 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); Allocates an array containing two elements
IntPtr pt = Marshal.allochglobal (marshal.sizeof (typeof (OSINFO)));
Marshal.Copy (Ptarr, 0, PT, 1); Copy pointer array
Getversionarray (PT, 2);//Call
//restore to Structure body 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);
three. Transmission of complex structures
1. Output parameters, structure body as a pointer outgoing
typedef struct
{
char name[20];
int age;
Double scores[30];
} Student;
class contains the structure body array type
typedef struct
{
int number;
Student students[50];
} Class;
Incoming complex structure test
Jnaapi int getclass (Class *pclass,int len);
//interface definition [DllImport ("Jnalib.dll", EntryPoint = "GetClass")] public static extern int GetClass (INTPTR p
V,int Len); struct definition//Student [StructLayout (layoutkind.sequential)] public struct Student {[MarshalAs (UnmanagedType.ByValTStr,
SIZECONST=20)] public string name;
public int age;
[MarshalAs (UnmanagedType.ByValArray, SizeConst =)] public double[] scores;
}//class [StructLayout (layoutkind.sequential)] public struct class {public int number; [MarshalAs (UnmanagedType.ByValArray, SizeConst = 50)]//Specify array size public student[] students;
Structure body Array Definition}//call complex structure Test int size = marshal.sizeof (typeof (Class)) * 50; IntPtr Pbuff = marshal.allochglobal (size);
Direct allocation of 50 elements of space, more convenient than marshal.copy getclass (Pbuff, 50);
class[] Pclass = new CLASS[50];
for (int i = 0; i < i++) {IntPtr ptr = new IntPtr (Pbuff.toint64 () + marshal.sizeof (typeof (Class)) * i);
Pclass[i] = (Class) Marshal.PtrToStructure (PTR, typeof (Class)); } marshal.freehglobal (Pbuff); Free Memory
2. Input parameters, assign values to complex structures as input parameters
For larger structure pointers, it is not possible to apply the struct type directly to the IntPtr type, at which point the native type needs to be converted to a pointer and assigned to the pointer
Call method: Marshal.structuretoptr (Stu, PTR1, True)
End ...
Turn from: http://tcspecial.iteye.com/blog/1675309