Wie gehe ich Zeiger auf eine DLL mit Win32: API?

stimmen
2

Ich versuche, in 3-Zeiger auf eine DLL-Funktion zu übergeben. Ich habe:

{

$ Code = 1;
$ Len = 100;
$ Str =“ x $ len;

$ Funktion = new Win32 :: API (DLLNAME, 'dllfunction', 'PPP', 'V');

$ Funktions-> Call ($ code, $ str, $ len);

}

Die DLL wird definiert als void dllfunction(int* a, char* str, int* len);die DLL alle Variablen durch die drei Zeiger darauf ändern wird.

Ich bin jedoch Speicherzugriffsfehler , wenn ich das laufen. Die Dokumentation für Win32 :: API angegeben , dass ich tatsächlich Variablennamen anstelle der Perl Variablenreferenzen verwenden sollten. Kann mir jemand sagen , was ich fehle? Vielen Dank.

*Mehr Informationen:

Ich habe printf()in der DLL die Adresse der drei Zeiger zu drucken, und printfin Perl die Referenz der drei Variablen auszudrucken. Und ich bekomme die folgende

DLL: Code = 0x10107458 Fehler = 0x10046b50 str = 0x10107460

Perl: Code = 0x101311b8 Fehler = 0x101312a8 str = 0x10131230

Jede Idee, warum die DLL wird immer die falschen Adressen?

****Mehr Informationen

Nach viel Debugging, fand ich heraus, dass dies geschieht, wenn von der DLL-Funktion zurückkehrt. I hinzugefügt printf ( \ n done); als letzte Zeile dieser DLL-Funktion, und dieser tut Ausgang, dann geht das Programm segfaults. Ich denke, sein Vorkommnis in Win32 :: API? Hat jemand diese Erfahrung gemacht?

Außerdem bin ich die Anfangsvariablen aller drei Variablen aus der DLL zugreifen können. So wird der Zeiger übergeben richtig, aber aus irgendeinem Grund verursacht es eine segfault wenn sie von der DLL zurück. Vielleicht Speicherzugriffsfehler es bei dem Versuch, die neuen Daten in das Perl-Variable zu kopieren?

Veröffentlicht am 09/12/2008 um 21:06
quelle vom benutzer
In anderen Sprachen...                            


4 antworten

stimmen
3

AH!! Ich habe es herausgefunden.

Das Problem war, das

  1. Und optional können Sie die Aufrufkonvention angeben, wird standardmäßig ‚__stdcall‘, alternativ können Sie angeben, ‚_cdecl‘.

Die DLL-Funktion wurde mit extern „C“ __declspec (dllexport) exportiert so dass ich dachte, vielleicht sollte ich ‚_cdecl‘ Flag werden.

Win32 :: API ( 'DLL', 'dllfunction', 'PPP', 'V', '_ cdecl');

funktioniert!

Dank jeder.

Beantwortet am 09/12/2008 um 23:30
quelle vom benutzer

stimmen
0

Ich bin kein Fenster Programmierer, aber zu sehen:

für Zeiger müssen Sie einen Variablennamen verwenden

für mich bedeutet die Variablennamen, nicht die Variablen selbst. Funktioniert das?

$function->Call('code', 'str', 'len');

oder vielleicht

$function->Call('$code', '$str', '$len');

Btw, ich würde erwarten , dass die Speicheradressen gleich sein. Win32::APImüssen die Perl - Datenelemente in etwas konvertieren, auf dem Windows verstehen kann , und ich bezweifle ernsthaft , würden sie den gleichen physikalischen Speicherplatz belegen.

Beantwortet am 09/12/2008 um 23:08
quelle vom benutzer

stimmen
0

OK, ich folgte Adams Link zu dieser Seite . Nach dass, sollte der Anruf sein:

$function->Call(code, $str, len)

Der Beispielcode verwendet eine Funktion mit einem LPSTR (im Wesentlichen ein char *) Parameter, und es verwendet die Variable als man erwarten würde, aber dieses Bit hier:

für Zeiger müssen Sie einen Variablennamen (keine Perl Referenzen, nur eine normale Variablenname) verwenden.

scheint darauf hinzudeuten , dass der Code , den ich in diesem Beitrag aufgeführten sollte funktionieren.

Beantwortet am 09/12/2008 um 22:09
quelle vom benutzer

stimmen
0

IANAPH, aber ich denke , Sie tun müssen, verwenden Referenz , etwa so:

$function->Call(\$code, \$str, \$len)

Der, den ich bin am wenigsten sicher ist $ str - es kann nicht eine Referenz benötigen. Die segfault kommt mit ziemlicher Sicherheit aus der DLL versucht, Speicheradresse 1 (oder 100, je nachdem , welche sie zuerst versucht , zu schreiben) zu schreiben.

Beantwortet am 09/12/2008 um 21:31
quelle vom benutzer

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more