Laden...

Einbinden einer undokumentierten DLL

Erstellt von Krzysztof vor 16 Jahren Letzter Beitrag vor 16 Jahren 1.766 Views
K
Krzysztof Themenstarter:in
11 Beiträge seit 2008
vor 16 Jahren
Einbinden einer undokumentierten DLL

Hallo zusammen!

Ich umschreibe mal zunächst meine Aufgabenstellung:
Ich habe hier ein VBA-Makro, welches eine DLL einbindet, die wohl vor langer, langer Zeit von Praktikanten oder so entwickelt wurde, sodass ich außer der DLL-Datei selbst keinerlei Informationen habe. Dieses Makro würde ich nun gerne durch eine C#-Applikation ersetzen.

Nun zum Problem:
Bisher (in VBA) wurde die DLL folgendermaßen eingebunden:

Private Declare Function init_table Lib "Can_DLL\source\can_anb.dll" Alias "@init_table$qqsiususucuspct6t6" _
                    (ByVal baud As Integer, ByVal globalmask As Integer, ByVal lokalmask As Integer, ByVal arbit As Byte, ByVal Arbitvalue As Integer, ByRef pfad As String, ByRef pfad As String, ByRef pfad As String) As Integer

und folgendermaßen aufgerufen:

init_table(125, 32767, 1024, 1, 1024, "", "", "")

Jetzt habe ich leider bereits einen Nachmittag mit Recherche verbracht, habe DllImport mit verschiedenen EntryPoints und CallingConventions ausprobiert und Tools ausprobiert, die aber allesamt mit meiner can_anb.dll anfangen konnten. Bei der DllImport-Einbindung lautet der Fehler immer

Das angegebene Modul wurde nicht gefunden. (Ausnahme von HRESULT: 0x8007007E) kann nicht geladen werden.

Ich muss dazu sagen, dass ich eigentlich weder vom Umgang mit DLL-Dateien, noch von C# oder C++ wirklich eine Ahnung habe. Auch die Tipps hier im Forum konnte ich leider nicht erfolgreich umsetzen.

Welchen Ansatz sollte ich ergreifen, bzw. wie lässt sich oben genannter VBA-Code am besten in C# übernehmen?

Ich bedanke mich schonmal im Voraus für die Umstände.

Gruß
Christoph

J
51 Beiträge seit 2007
vor 16 Jahren

Poste doch mal den Code deines DLL Imports in C# !

K
Krzysztof Themenstarter:in
11 Beiträge seit 2008
vor 16 Jahren
[DllImport(dllFile, EntryPoint = "@init_table$qqsiususucuspct6t6")]
        private static extern void init_table(int baud, int globalmask, int lokalmask, byte arbit, int Arbitvalue, string pfad, string pfad1, string pfad2);

funktioniert jetzt. Da hatte ich gestern wohl nur einen kleinen Detailfehler drin und mich anschließend durch meine eigene Google-Recherche verrückt machen lassen. Tschuldigung.

Nun habe ich aber ein neues Problem:

Private Declare Function init_handle Lib "Can_DLL\source\can_anb.dll" Alias "@init_handle$qqsuspus" _
                    (ByVal identifier As Integer, ByRef handle As Integer) As Integer

habe ich durch

[DllImport(dllFile, EntryPoint = "@init_handle$qqsuspus")]
        private static extern void init_handle(int identifier, ref int handle);

ersetzt.
In VBA wurde dies mit

init_handle(384, handle_j1)

aufgerufen, wobei handle_j1 ein globaler integer ist.
Ich würde dies gerne mit

init_handle(384, ref handleJoystick1);

aufrufen, wobei handleJoystick1 momentan ein public static int meiner Klasse ist. (Lokal hat leider ebenfalls nicht funktioniert.)
Das Problem ist nun: Die DLL scheint auf handleJoystick1 nicht schreiben zu können, was sie in VBA aber tut.
Wie muss ich diese Variable deklarieren, damit die DLL darauf schreiben kann?

S
8.746 Beiträge seit 2005
vor 16 Jahren

Die Parameter sind ok, aber du hast void als Rückgabewert statt int.

K
Krzysztof Themenstarter:in
11 Beiträge seit 2008
vor 16 Jahren

Danke für den Tipp. Habe nun void durch int ersetzt. Leider keine Veränderung.

Hätte ich aber so auch nicht erwartet, denn die init_handle-Funktion der DLL bekommt von VBA unter anderem die Referenz auf den Integer handle übergeben und modifiziert diesen. Hierbei sollte der eigentliche Rückgabewert der init_handle-Funktion, der meiner Erfahrung nach immer 0 zu sein scheint, meines Erachtens keine Rolle spielen.

Mein Problem ist ja, dass in meiner C#-Implementierung der referenziell übergebene Integer nicht von der DLL modifiziert werden kann.

(Ich bin mir nicht mal sicher, ob die DLL überhaupt darauf zugreifen kann, da diese sehr schweigsam ist).

915 Beiträge seit 2006
vor 16 Jahren

Bin mir nicht sicher aber glaube deie string parameter könnten evtl in VBA anders intepretiert werden - bin mir da etwas unsicher was das angeht aber probieren kann ja nicht schaden .-)


[DllImport(dllFile, EntryPoint = "@init_table$qqsiususucuspct6t6", CharSet=CharSet.Unicode, ExactSpelling=true))]
        private static extern int init_table(int baud, int globalmask, int lokalmask, byte arbit, int Arbitvalue, string pfad, string pfad1, string pfad2);

Wie vernichtet stand Andreas unter den flammenden Augen seiner Kunden.
Ihm war's, als stünde des Schicksals dunkle Wetterwolke über seinem Haupte X(

K
Krzysztof Themenstarter:in
11 Beiträge seit 2008
vor 16 Jahren

Habe deinen Code soweit übernommen.

Zu meinem Bedauern hat sich nichts geändert.

Die init_table-Funktion scheint aber durchaus zu funktionieren, da das Hardwaregerät "belegt" ist, das heißt, von anderen Tools nicht mehr verwendet werden kann, sobald diese Funktion aufgerufen wurde.

Der Fehler muss also irgendwo in meiner Verwendung der init_handle liegen, denke ich.

K
Krzysztof Themenstarter:in
11 Beiträge seit 2008
vor 16 Jahren

OK, die Sache läuft. Schuld war im Endeffekt die DLL selbst , wobei, glaube ich, auch ein int in VBA ein short in C# sein sollte.

Vielen Dank für alle Antworten