Hoofdstuk 13 - Les 1

Component Object Model (COM) is een unmanaged object georiënteerd model en bevatten classes, methods en types. Type libraries kunnen een standalone .tlb bestand zijn die een type definiëren of ze kunnen in een dll, exe, ocx of olb bestand zitten.

De Type Library Importer (tlbimp.exe) maakt een interop assembly die vervolgens geimporteerd kan orden in Visual studio zodat er gebruik gemaakt van kan worden.

Er zijn twee manieren om unmanaged DLLs te gebruiken binnen VS.
  1. Voeg een reference toe aan het project
  2. Maak gebruik van de System.Runtime.InteropServices namespace en gebruik het import attribuut
Het .NET Frameork gebruikt marshaling om data te versturen tussen het .NET Framework en COM. Marshalingis het process die ervoor zorgt dat alle parameters correct worden doorgegeven. De types in .NET kunnen anders gedefinieerd zijn in een COM. Voorbeeld een string in .NET is in een COM object een BStr.

Vaak zijn de standaard marshaling instellingen voldoende, maar de instellingen kunnen ook handmatig bepaald worden. Via de DLLImport attribuut kunnen er verschillende properties worden gezet.
class Program
{
[DLLImport("user32.dll", EntryPoint="MessageBox")]
private static extern int ShowBox(IntPtr, hWnd, String text, String caption, uint type);

static void Main(string[] args)
{
ShowBox(new IntPtr(0), "Hallo dan!", "Mijn box", 0);
}
}

De marshal class biedt een aantal static methods aan waaronder de Marshal.GetLastWin32Error methode die een int teruggeeft van de laatste fout die is opgetreden.

Unmanaged methods hebben vaak een struc als parameter. De layout van een struct kan gespecificeerd worden door gebruik te maken van de StructLayout en FieldOffset attribuut. Voorbeeld van een unmanaged methode:

bool PtInRect(const RECT *lprc, POINT pt)

Een * betekent pass by reference.
[StructLayout(LayoutKind.Sequential)]
public struct Point
{
public int x;
public int y;
}

[StructLayout(LayoutKind.Explicit)]
public struct Rect
{
[FieldOffset(0)]
public int left;

[FieldOffset(4)]
public int top;

[FieldOffset(8)]
public int right;

[FieldOffset(12)]
public int bottom;
}

class Win32API
{
[DLLImport("User32.dll")]
public static extern bool PtinRect(ref Rect r, Point p);
}
LayoutKind.Auto geeft de CLR full control over de layout, inclusief de volgorde van de velden. Sequential staat het toe de CLR de layout te bepalen, maar wel in de gestelde volgorde. Bij Explicit moet de ontwikkelaar het aantal bytes voor elk veld in de structure specificeren door gebruik te maken van de FieldOffset attribuut.

Sommigie COM methods hebben als parameter een methode om de result value terug te geven. Parameters van zo'n methode beginnen vaak met lp (long pointer) en eindigen met Func (function). Dit wordt ook wel een callback genoemd.Voorbeeld:

bool EnumWindows(WNDENUMPROC lpEnumFunc, LParam lparam)

// Maak een delegate voor de methode
public delegate bool CallBack(int hwnd, int lparam);

public class EnumReportApp
{
// Maak een prototype van de functie
[DLLImport("User32.dll")]
public static extern int EnumWindows(CallBack x, int y);

public static void Main()
{
// Maak een instantie van de delegate
CallBack mc = new CallBack(EnumReportApp.Report);

// Roep de functie aan
EnumWindows(mc, 0);
}

// Declareer de method om de callback af te handelen
public static bool Report(int hwnd, int lparam)
{
Console.WriteLine("Window handle is: " + hwnd);

return true;
}
}

Voor gebruikersgemak wordt er vaak een wrapper class om een unmanaged class gemaakt.

Reacties

Populaire posts van deze blog

[SQL Server] varchar vs nvarchar

MS Sql 70-461: Chapter 5

[C#] Class serialiseren en deserialiseren