1. What are the restrictions on the types of P/invoke messages?
Return Value
• It can only be a value type of less than or equal to 32 bits
• No floating point
• Parameters
• Only messages can be directly copied to the local structure.
• Types that can be directly copied to the local structure-> the hosted and local structures have the same representation in the memory
• Type not directly copied to the local structure-> memory conversion required
• Since only the types in the local structure are directly copied, all objects are fixed and will not be copied.
• Exception: Passing string byval in VB. NET
• This means that you cannot ban and process nested objects because it requires memory conversion (not directly copied to the local structure)
• It can only be a value type of less than or equal to 32 bits
• Pass VALUE IN STACK
• Exception: float32
• Reference
• Transfer reference types that can be directly copied to the local structure
• Pass the reference to the Value Type
• This is the method for passing float32
• An array of value types can be passed. The local machine obtains the pointer to the first object, which is arranged in the order you want.
• String is special. It transmits character Arrays-> immutable
• Stringbuilder is special. It transmits character Arrays-> variable (length must be transferred separately)
• Note: C # bool has only eight bits, not Win32 bool
• Alignment: Default compiler alignment (4 bytes)
• Inclual. getlastwin32error supports getlasterror () Semantics
• Not supported:
• Replicalas: data types that are not directly copied to the local structure are not supported.
• Structlayout: unable to change the layout
• Delegate)
• Datetime
• Only the default call conventions are supported.
2. How to convert byte [] to intptr?
The first is insecure.CodeBlock to access the pointer directly pointing to the byte array:
Unsafe {byte [] test = new byte [5]; fixed (byte * P = & test [0]) {* P = 0xff ;}}
You can also use gchandle to obtain the object:
Using system. runtime. interopservices;
Byte [] test = new byte [5];
Gchandle hobject = gchandle. alloc (test, gchandletype. Pinned );
Intptr pobject = hobject. addrofpinnedobject ();
If (hobject. isallocated)
Hobject. Free ();
Finally, you can create a memory block through localalloc and mail the data to the memory block for processing:
[Dllimport ("coredll. DLL ", setlasterror = true)] public static extern intptr localalloc (uint uflags, uint ubytes); [dllimport (" coredll. DLL ", setlasterror = true)] public static extern intptr localfree (intptr hmem); [dllimport (" coredll. DLL ", setlasterror = true)] public static extern intptr localrealloc (intptr hmem, uint ubytes, uint fuflags); Public const uint lmem_fixed = 0; Public const uint lmem_moveable = 2; public const uint lmem_zeroinit = 0x0040; byte [] test = new byte [5]; intptr P = localalloc (lmem_fixed | lmem_zeroinit, (uint) test. length); If (P = intptr. zero) {Throw new outofmemoryexception ();} else {marshal. copy (test, 0, P, test. length );}