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()