Call into Unmanaged dlls from C#

Overview 

  • PInvoke is used to invoke unmanaged dlls
    • kernel32.dll
      • process loading
      • context switching
      • file, memory i/o
    • user32.dll
      • windows, menus, dialog boxes, icons, etc.
    • GDI32
      • drawing capabilities

Declare a method in c# to access unmanaged function

  • Declare this method as both
    • static
    • extern
  • Apply attribute System.Runtime.InteropServices.DllImportAttribute to specify
    • dll file
    • name of the unmanaged function
  • Examples

      [DllImport("kernel32.dll", EntryPoint="GetPrivateProfileString")]
      private static extern int GetPrivateProfileString(string lpAppName,
      string lpKeyName, string lpDefault, StringBuilder lpReturnedString,
      int nSize, string lpFileName);

      [DllImport("kernel32.dll", EntryPoint="WritePrivateProfileString")]
      private static extern bool WritePrivateProfileString(string lpAppName,
      string lpKeyName, string lpString, string lpFileName);

Call unmanaged function that uses callbacks

  • Declare a delegate with the required signature for the callback
  • Define call back function to be passed
  • Pass the callback to the function
  • Example

    // The signature for the callback method.
    public delegate void OnXMConnect();
    public delegate void OnXMDisconnect();
    // The call back methods
    private static void OnXMConn(){
    Console.WriteLine("Connected");
    }
    private static void OnXMDisconn(){
    Console.WriteLine("DisConnected");
    }// Pass the callbacks to unmanaged function
    private static void TestXM(){
    USB_RegisterCallbacks(OnXMConn, OnXMDisconn);
    }

Pass Struct as parameter

  • Define a class to represent C struct
  • Annotate with [StructLayout(LayoutKind.Sequential)]
  • Declare struct members as class member variables
  • Annotate variables with [MarshalAs…] if needed
  • Example

    // Define struct as a class
    [StructLayout(LayoutKind.Sequential)]
    public class OSVersionInfo
    {
    public int dwOSVersionInfoSize;
    public int dwMajorVersion;
    public int dwMinorVersion;
    public int dwBuildNumber;
    public int dwPlatformId;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst=128)]
    public string szCSDVersion;
    }// Use the class
    [DllImport("kernel32.dll")]
    public static extern bool GetVersionEx([In, Out] OSVersionInfo osvi);private static void TestStruct()
    {
    OSVersionInfo osvi = new OSVersionInfo();
    osvi.dwOSVersionInfoSize = Marshal.SizeOf(osvi);GetVersionEx(osvi);

    Console.WriteLine("Major version: {0}", osvi.dwMajorVersion);
    Console.WriteLine("Minor version: {0}", osvi.dwMinorVersion);
    }

// if RECT is a class, not struct

[DllImport("user32.dll")]
public static extern int GetWindowRect(int hwnd, [MarshalAs(UnmanagedType.LPStruct)] RECT rc);

This entry was posted in c#. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *


*

This site uses Akismet to reduce spam. Learn how your comment data is processed.