DLLExport .NET ohne C++/CLI

Möchte man Bibliotheken in .NET nutzen, ist das relative simple.. man Importiert diese anhand ihrer Signatur und kann sie benutzen.

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);

Möchte man nun aber in C/C++ eine Bibliothek aus .NET nutzen, die man in VB oder C# geschrieben hat, ist das nicht möglich. Es gibt schlichtweg keine Möglichkeit mit dem Visual Studio Methoden zu exportieren. Es müßte ein Attribute  [DLLExport] her der die Methoden mit __stdclass exportiert.

Und auf die Lösung zu dem Problem bin ich heute gestoßen. Und die Lösung ist so „simple“ und einfach wie man es bei weitem nicht erwartet hätte. Die Lösung steht unter der CPOL auf codeprojekt.de und wurde von Dark Daskin veröffentlicht.

Die Lösung besteht einfach gesagt darin dass die DLL wieder disassembliert wird und um den Funktionsrumpf einer __stdcall Methode erweitert wird + einige andere Attribute. Danach wird sie wieder zusammen gesetzt.

Man lädt sich als erstes die DLL von codeprojekt.com und kopiert die DLLExporter.exe in ein neues Klassenprojekt von Visual Studio. Danach fügt man die DllExporter.exe als Verweis hinzug. Mit dem Objektbrowser kann man nun verifizieren dass die Klasse Managementcode enthält. Was wir aber nutzen werden ist legendlich das Attribute [DLLExport].

Bevor wir aber arbeiten können müssen wir ein Postbuilderereigniss für das Projekt definieren.

DllExporter.exe $(TargetFileName)
move $(TargetName).Exports$(TargetExt) $(TargetFileName)

Damit bearbeitet der DLLExporter die entstandene Zieldatei noch und fügt den notwendigen Rumpf ein damit man die DLL später mittels DLLImport nutzen könnte.

So nun brauch man nur noch eine Klasse mit Funktionen zu bauen und den exportierenden Klassen das Attribute [DLLExport] anzugeben. Und nach dem Erstellen liegt eine nutzbare DLL im bin\Debug Verzeichnis.

using System;
using System.Runtime.InteropServices;

namespace GC_DLL
{
 public class Class1
 {
 // http://www.codeproject.com/KB/dotnet/DllExporter.aspx

 [DllExporter.DllExport]
 public static void HelloWorld([MarshalAs(UnmanagedType.LPTStr)]string name)
 {
 Console.WriteLine("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\n{0}\n\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", name);
 }
 }
}

In C# könnte man nun die DLL auch wieder wie folgt importieren:

[DllImport("GC_DLL.dll", CharSet = CharSet.Unicode)]
 public static extern string HelloWorld(string name);

und dann HelloWorld(„dies ist ein Test“) ausführen.

Für weitere Informationen und ausführliche Beispiele würde ich hier auf die Projektwebseite verweisen. Die Möglichkeit hier überhaupt sowas machen zu können ist erstmal genial und erspart uns in einem aktuellem Projekt eine Menge Einarbeitungszeit – da die Alternative darin bestünde nun in C/C++ was zu implementieren wo der Funktionsumfang bei weitem nicht so gut ist als in .NET.

Quelle: http://www.codeproject.com/KB/dotnet/DllExporter.aspx

Über den Autor Danny Sotzny

Hallo, ich bin Danny Sotzny und bin Software- entwickler und Fotograf. Dabei beschäftige ich mich mit aktuellen Technologien und bekannten Problemen. Schwerpunkte setze ich bei der Webentwicklung (PHP/JS) und der Software- entwicklung mit .NET (C#). Der Blog dient für mich selbst als Gedächtnishilfe für typische und alltägliche Probleme, aber auch persönliche Erlebnisse werden veröffentlicht. Ich betreibe zusätzlich noch Foto-Sotzny.de für meine Fotografien und sotzny.net, was meine Webseite für die Softwareentwicklung ist.

Leave a Reply

See also:

%d Bloggern gefällt das: