DLLImport attribute

The attribute, [DllImport()], falls under the DllImportAttribute class. It provides the information required to call a function exported from an unmanaged DLL. The minimum prerequisite is that we should pass the name of the DLL which contains the entry point. We can apply this attribute straightforwardly to C# and C++ function definitions. Let's check what the DllImport attribute has inside it. In the code window, click on DllImport and press the F12 key (referred to as the go-to definition). This key is bound to the de-compile command in Visual Studio and will de-compile the selected type, if it can. Upon de-compilation, Visual Studio will display the de-compiled code in a new window. In the de-compiled code of DllImport, we can see each and every parameter. The code is very well commented and self-explanatory, as can be seen here:

namespace System.Runtime.InteropServices
{
//
// Summary:
// Indicates that the attributed method is exposed by an unmanaged
dynamic-link
// library (DLL) as a static entry point.
[AttributeUsage(AttributeTargets.Method, Inherited = false)]
public sealed class DllImportAttribute : Attribute
{
//
// Summary:
// Enables or disables best-fit mapping behavior when
converting Unicode characters
// to ANSI characters.
public bool BestFitMapping;
//
// Summary:
// Indicates the calling convention of an entry point.
public CallingConvention CallingConvention;
//
// Summary:
// Indicates how to marshal string parameters to the method and
controls name mangling.
public CharSet CharSet;
//
// Summary:
// Indicates the name or ordinal of the DLL entry point to be
called.
public string EntryPoint;
//
// Summary:
// Controls whether the
System.Runtime.InteropServices.DllImportAttribute.CharSet
// field causes the common language runtime to search an
unmanaged DLL for entry-point
// names other than the one specified.
public bool ExactSpelling;
//
// Summary:
// Indicates whether unmanaged methods that have HRESULT or
retval return values
// are directly translated or whether HRESULT or retval return
values are automatically
// converted to exceptions.
public bool PreserveSig;
//
// Summary:
// Indicates whether the callee calls the SetLastError Win32
API function before
// returning from the attributed method.
public bool SetLastError;
//
// Summary:
// Enables or disables the throwing of an exception on an
unmappable Unicode character
// that is converted to an ANSI "?" character.
public bool ThrowOnUnmappableChar;

//
// Summary:
// Initializes a new instance of the
System.Runtime.InteropServices.DllImportAttribute
// class with the name of the DLL containing the method to
import.
//
// Parameters:
// dllName:
// The name of the DLL that contains the unmanaged method. This
can include an assembly
// display name, if the DLL is included in an assembly.
public DllImportAttribute(string dllName);

//
// Summary:
// Gets the name of the DLL file that contains the entry point.
//
// Returns:
// The name of the DLL file that contains the entry point.
public string Value { get; }
}
}

We can characterize the following attributes with the DLL name:

  • ThrowOnUnmappableCharThis field is False by default, which means the ThrowOnUnmappableChar field is disabled. Best-fit mapping empowers the Interop marshaler to give a nearby coordinating character when no correct match exists, every time the Interop marshaler changes over an unmappable character. For example, the marshaler changes over the Unicode character into c for unmanaged techniques that acknowledge ANSI characters. A few characters do not have a best-fit portrayal; these are called unmappable characters. These unmappable characters are typically changed over to the default ? ANSI character.
  • SetLastError: By default, SetLastError is set to false, but in Visual Basic it is set to true by default. GetLastError is called by runtime marshaler and it caches the return value so it is not overwritten by other API calls. You can recover the error code by calling GetLastWin32Error.
  • ExactSpelling: The ExactSpelling field, as the name suggests, impacts the behavior of the CharSet field to figure out the exact entry point name to invoke. If the ExactSpelling field is set to False, Platform Invoke looks for the unmangled alias first; if the unmangled alias is not found, then it will look for the mangled name.
  • BestFitMapping: By default, the BestFitMapping field is true. On the off chance that this field is true, it overrides any level settings for System.Runtime.InteropServices.BestFitMappingAttribute. Best-fit mapping empowers the Interop marshaler to give a nearby matching character when no correct match exists. For instance, the marshaler changes over the Unicode copyright character to c for unmanaged functions that acknowledge ANSI characters. A few characters do not have a best-fit representation, and these characters are called unmappable. Unmappable characters are generally changed over to the default ? ANSI character.
  • CallingConventionSpecifies the calling convention required to call methods implemented in unmanaged code. It is defined as an enumeration. The values of this enumeration are used to specify the calling conventions. This determines how a function is called, for example, the argument passing order behaviour is set to right to left, or stack maintenance responsibility such as the Calling function pops the arguments from the stack, and so on. There are fundamentally five calling convention fields: CdeclStdCall, FastCall, ThisCall, and Winapi. The default is StdCall for unmanaged functions with P/Invoke. More about this can be read at: https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.callingconvention(v=vs.110).aspx.
  • StdCall: The callee cleans the stack. To call unmanaged functions with Platform Invoke, this is the default convention. 
  • Cdecl: This empowers calling functions with variable args, which means it is good to use for functions that use a variable number of parameters, for example, on the Windows platform, the System.Runtime.InteropServices.CallingConvention.Cdecl convention will act as: Argument-passing order | right to left
  • Winapi: This part isn't really a calling convention, rather it utilizes the default platform calling convention. For instance, in Windows, the default is StdCall, and on Windows CE .NET, it is Cdecl.
  • ThisCall: The primary parameter is the pointer and is put away in register ECX. Other parameters are pushed on the stack. This calling convention is utilized to call functions on classes exported from an unmanaged DLL.
  • CharSet: It determines the marshaling conduct of string parameters and is useful for indicating which entry point name to invoke (the correct name given or a name finishing with net or As). The default list part for C# is CharSet.Ansi and the default count part for C++ is CharSet.
  • Entrypoint: You can determine the entry point name by providing a string showing the name of the DLL containing the entry point, or you can recognize the entry point by its ordinal. Ordinals are prefixed with the # sign. We can utilize the DllImportAttribute.EntryPoint field to indicate a DLL function by name or ordinal. On the off chance that the name of the function in your function definition is the same as the entry point in the DLL, you don't need to expressly recognize the function with the EntryPoint field. Utilize syntax to demonstrate a name or ordinal:
[DllImport("dllname", EntryPoint="MethodName")]
[DllImport("dllname", EntryPoint="#XYZ")]

Notice that you should prefix an ordinal with the pound sign (#). To know the entry point of DLL, we can use DUMPBIN.exe also. Just open the Developer Command Prompt and go to the DLL location and type the command, DUMPBIN /EXPORTS ExampleDLL.dll. Running this command returns information about the entry point and functions of DLL, shown as follows:

It gives all the information about DLL such as:

    • It has one ordinal base
    • It has three functions
    • The names of functions and their ordinal value

There are many commands which we can use to get information about DLL. To find out all the commands, enter the following command, Dumpbin.exe. It gives us a list of commands that we can use.

Certain Unicode characters are changed over to risky characters, for example, the oblique punctuation line \ character, which can unintentionally change a way. By setting the ThrowOnUnmappableChar field to genuine, you can flag the nearness of an unmappable character to the guest by tossing a special case.

You can't change the default values given by the BestFitMapping and ThrowOnUnmappableChar fields when passing a managed array whose components are ANSI characters or LPSTRs to an unmanaged safe exhibit. Best-fit mapping is constantly empowered and no special case is tossed. Know that this blend can trade-off your security information.