I have the following marshalling code in my project. I have few questions on this.
[DllImport=(Core.dll, SetLastError=true, EntryPoint="CoreCreate", CharSet="CharSet.Ansi", CallingConvention="CallingConvention.Cdecl")]
internal static extern uint CoreCreate(ref IntPtr core);
- Why ‘internal static extern’ is required? Is this compulsory? Why this is used?
- What is SetLastError?
[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Ansi)] internal struct Channel { internal byte LogicalChannel; }
Why LayoutKind.Sequential?
The
internalmodifier just set visibility of your method. It’s not required to beinternalso you can declare the methodprivateorpublicas you need and as you would do with any other standard method.The
staticmodifier is required because it’s not an instance method and that method doesn’t know any class (it hasn’t athispointer).Finally
externis required to inform the compiler that the method isn’t implemented here but in another place (and you’ll specify where using attributes). Eveyexternmethod must be declaredstatictoo (because it’s a simple function call without any knowledge about objects).It indicates that method may change the thread’s last-error code value. See the
GetLastError()function for details about this. If the called function will change this value then it’s a good thing to setSetLastErrortotrue, from MSDN:In short it saves the value returned by GetLastError() to an internal cache so any other call to system API (even internal to others framework functions) won’t overwrite that value.
Class layout in .NET isn’t required to be sequential in memory (sequential = if
Ais declared beforeBthen memory layout hasAbeforeB). This is not true in C where the declaration order matters (declaration is used by the compiler to understand the layout, in memory, of raw data). If you have to interop with C functions then you have to be sure about the layout of the data you pass them. This is howLayoutKind.Sequentialworks: it instructs the compiler to respect the declaration sequential order for data in thestruct. This is not the only option to interop with unmanaged world, you can even explicitly set the offset (from structure beginning) of each field (see LayoutKind.Explicit).