Wie man .NET Dll's in Blitz einbinden und benutzen kann
Übersicht

![]() |
JolinahBetreff: Wie man .NET Dll's in Blitz einbinden und benutzen kann |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich habe mich schon mehrmals gefragt ob es denn nicht möglich ist auch mit .NET erstellte Dll's in Blitz zu benutzen.
Als ich mit Google gesucht hab wurd ich dann zu meinem Erstaunen auch recht schnell fündig. Man muss natürlich das .NET Framework SDK installiert haben, wie man die Dll's dann macht solltet ihr auch selber wissen. Es gibt 2 Kommandozeilenprogramme in der SDK die man hierfür benötigt. ildasm.exe und ilasm.exe Mit der ersten exe kann man die DLL in IL Code disassemblieren lassen. Mit der zweiten wieder zurück assemblieren. Dieser Code ist sozusagen die Zwischensprache von .NET. Egal ob man C#,VB oder C++ .Net programmiert, es werden alle Programme vor dem kompilieren immer in diese Zwischensprache kompiliert. Von dieser aus dann zu dem eigentlichen Programm. Das kann man nun Nutzen um die .Net Dll's manuell abzuändern. Der Grund warum die normalen .Net Dll's nicht in Blitz funktionieren ist das diese sogenannten Managed Code verwenden. Damit es funktioniert muss man dafür sorgen das die Funktionen als "unmanaged" Code exportiert und aufgerufen werden. 1. So kann man die DLL disassemblieren in eine il Datei. Der /OUT: Parameter gibt die il Datei an die generiert wird, danach folgt die DLL selbst. Code: [AUSKLAPPEN] ildasm.exe /OUT:DLL.il DLL.dll Nun kann man die il Datei mit nem Text Editor bearbeiten. Such nach der Zeile: Code: [AUSKLAPPEN] .corflags 0x00000001 Dieses Flag muss auf 0x00000002 geändert werden. Wenn man das nicht macht beachtet Windows die Änderungen die wir gleich machen gar nicht erst. Unter die .corflags Zeile kommt dann folgendes: Code: [AUSKLAPPEN] .vtfixup [1] int32 fromunmanaged at VT_01 .data VT_01 = int32(0) vtfixup Ist so eine Art Tabelle wo man die Adresse der Methode angibt die man exportieren will. Das [1] gibt an wie viele Felder die Tabelle hat. Zur Zeit nur 1 da wir nur 1 Funktion exportieren wollen. Der zweite Parameter legt fest ob es 32bit oder 64bit ist. Und fromunmanaged bedeutet eben das die Funktion als unmanaged aufgerufen werden soll. Das VT_01 ist eine Variable die die Adresse wo die Tabelle beginnt speichert. Die .data Zeile erstellt diese Variable eigentlich erst, sie ist vom Typ int32 und hat den Anfangswert 0. In diese Variable wird dann automatisch vom Assembler die richtige Funktionsadresse eingetragen. Aber damit das geht muss man in der Funktion selbst noch 2 Einträge machen: Original Code ohne Änderungen: In meinem Beispiel die Funktion void MyBox(string name) mit C# geschrieben. Zuerst kommt noch ein Namespace und eine Klasse. Code: [AUSKLAPPEN] .namespace DLL { .class public auto ansi beforefieldinit Class1 extends [mscorlib]System.Object { .method public hidebysig static void MyBox(string text) cil managed { // Code size 8 (0x8) .maxstack 1 IL_0000: ldarg.0 IL_0001: call valuetype [System.Windows.Forms]System.Windows.Forms.DialogResult [System.Windows.Forms]System.Windows.Forms.MessageBox::Show(string) IL_0006: pop IL_0007: ret } // end of method Class1::MyBox .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { // Code size 7 (0x7) .maxstack 1 IL_0000: ldarg.0 IL_0001: call instance void [mscorlib]System.Object::.ctor() IL_0006: ret } // end of method Class1::.ctor } // end of class Class1 Jetzt zu den 2 Einträgen die noch fehlen: Code: [AUSKLAPPEN] ... ... .method public hidebysig static void MyBox(string text) cil managed { .vtentry 1 : 1 //*** 1.Zeile *** .export [1] as um_MyBox //*** 2.Zeile *** // Code size 8 (0x8) .maxstack 1 IL_0000: ldarg.0 IL_0001: call valuetype [System.Windows.Forms]System.Windows.Forms.DialogResult [System.Windows.Forms]System.Windows.Forms.MessageBox::Show(string) IL_0006: pop IL_0007: ret } // end of method Class1::MyBox ... ... .vtentry 1 : 1 Dieser Befehl sorgt dafür das die Funktions Adresse in VT_01 geschrieben wird. Der erste Parameter (getrennt durch das ":") bedeutet in welcher .vtfixup Zeile es eingetragen wird. Der zweite in welcher Tabellen Spalte. Wir haben nur 1 .vtfixup Zeile also ist der erste Parameter 1. Diese vtfixup Tabelle hat auch nur [1] feld, also wird es vermutlich auch 1 sein. .export [1] as um_MyBox Diese Zeile sorgt dafür das es Schlussendlich "unmanaged" exportiert wird. [1] ist die Feldnummer der Tabelle. Der name nach as ist der Export name der Funktion. Der kann genau gleich sein wie die Managed Funktion aber ich bevorzuge das Präfix um_ für unmanaged. Hat man das nun alles geändert muss man nur noch aus der .il Datei wieder ne Dll machen. Dazu verwendet man nun ilasm.exe Code: [AUSKLAPPEN] ilasm.exe /OUT:DLL.dll DLL.il /DLL OUT bestimmt wieder die Ausgabe Datei, hier diesmal die DLL. Der nächste Parameter ist die Source IL Datei. Und die Option /DLL darf man nicht vergessen damit auch wirklich eine DLL gemacht wird. Nun ganz normal ins userlib Verzeichnis von BB kopieren und ne entsprechende .decls Datei schreiben: Code: [AUSKLAPPEN] .lib "DLL.dll" MyBox(text$) : "um_MyBox" Hier muss darauf geachtet werden den Namen zu benutzen den man bei der .export Zeile angegeben hat. Wie geht man vor wenn man mehrere Funktionen exportieren will. Entweder macht man für jede Funktion eine neue .vtfixup und .data Zeile, wobei jedesmal eine andere Variable verwendet werden muss (VT_01,VT_02,VT_03 usw.), oder man erhöht die Anzahl Tabellenfelder in der .vtfixup Zeile. In jeder Funktion muss ausserdem die .vtentry und .export Zeile drin sein. Also 1.Möglichkeit: Code: [AUSKLAPPEN] .vtfixup [1] int32 fromunmanaged at VT_01 .data VT_01 = int32(0) .vtfixup [1] int32 fromunmanaged at VT_02 .data VT_02 = int32(0) // In der ersten Funktion: .vtentry 1 : 1 .export [1] as um_first // In der zweiten Funktion: .vtentry 2 : 1 .export [1] as um_second // Warum 2 : 1, weil dieser eintrag dann in der zweiten .vtfixup Zeile ist in Feld 1 2. Möglichkeit: Code: [AUSKLAPPEN] .vtfixup [2] int32 fromunmanaged at VT_01 .data VT_01 // 1. Funktion .vtentry 1 : 1 .export [1] as um_first // 2. Funktion .vtentry 1 : 2 .export [2] as um_second // Diesmal ist alles in der ersten .vtfixup. Jedoch die 2. Funktion im 2. Feld. // Bei Export muss dann wahrscheinlich auch das Feld 2 angegeben werden. // Ich habe es jedoch noch nicht getestet. Schlusswort: In C# funktionierte bei mir alles super. In VB.Net hatte ich jedoch Probleme mit der String übergabe, obwohl ich in C# den Parameter auch als String und nicht etwa als Char[] behandelt habe. Naja einfach ausprobieren ![]() |
||
![]() |
Artemis |
![]() Antworten mit Zitat ![]() |
---|---|---|
Und wie schreibt man DLLs in C#, sodass man sie so nutzen kann?? | ||
Klaas |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Wer des Englischen mächtig ist sollte dazu auch mal nen Blick auf dies hier werfen:
http://www.blitzbasic.com/code...p?code=716 |
||
![]() |
Artemis |
![]() Antworten mit Zitat ![]() |
---|---|---|
ja danke!!
cool!! ![]() |
||
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group