Accessing Unmanaged Code from Managed Code
(or How to Call a C++ Function from C# and VB.NET)

 

 

See p. 237-239 in Programming Microsoft Windows with C#, by Charles Petzold.

 

Platform Invocation Services (PInvoke) – mechanism for calling functions exported from DLLs.  Can be used to call Win32 API functions or custom functions created in a language like C++.

 

 

Example C++ Function:

 

#define EXPORT extern "C" __declspec (dllexport)

 

EXPORT void MyDrawLine(HDC hdc, int x1, int y1, int x2, int y2,

                              COLORREF color, int width)

{

  HPEN hPen = CreatePen(PS_SOLID, width, color);

  HPEN hPenSave = (HPEN) SelectObject(hdc, hPen);

 

  MoveToEx(hdc, x1, y1, NULL);

  LineTo(hdc, x2, y2);

 

  SelectObject(hdc, hPenSave);

  DeleteObject(hPen);

}

 

 

 

Assume the code above was compiled into a DLL called graphiclib.dll.  It could then be accessed like so:

 

C# Example Call:

 

using System.Runtime.InteropServices;

 

struct ColorRef

{

  public byte red, green, blue;

  private byte unused;

 

  public ColorRef(byte r, byte g, byte b)

  {

    red = r;

    green = g;

    blue = b;

    unused = 0;

  }

}

 

[DllImport("GraphicLib.dll")]

       private static extern void MyDrawLine(System.IntPtr hdc, int x1, int y1,

int x2, int y2, ColorRef color, int width);

 

Graphics g = CreateGraphics();

System.IntPtr hdc = g.GetHdc();
ColorRef red = new ColorRef(255, 0, 0);

MyDrawLine(hdc, 0, 0, 150, 200, red, 1);

g.ReleaseHdc(hdc);

g.Dispose();

 

 

VB.NET Example Call:

 

Imports System.Runtime.InteropServices

 

Structure ColorRef

  Public red, green, blue As Byte

  Private unused As Byte

 

  Public Sub New(ByVal r As Byte, ByVal g As Byte, ByVal b As Byte)

    red = r

    green = g

    blue = b

    unused = 0

  End Sub

End Structure

 

Declare Auto Sub MyDrawLine Lib "GraphicLib.dll" (ByVal hdc As System.IntPtr, _

ByVal x1 As Integer, ByVal y1 As Integer, ByVal x2 As Integer, ByVal y2 As Integer, _

ByVal color As ColorRef, ByVal width As Integer)

 

Dim g As Graphics = Me.CreateGraphics()

Dim hdc As System.IntPtr = g.GetHdc()

Dim red As New ColorRef(255, 0, 0)

MyDrawLine(hdc, 0, 0, 150, 200, red, 1)

g.ReleaseHdc(hdc)

g.Dispose()