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