| Autor |
Beitrag |
wulfskin
      
Beiträge: 1349
Erhaltene Danke: 1
Win XP
D5 Pers (SSL), D2005 Pro, C, C#
|
Verfasst: Do 11.11.04 23:22
Hallo,
die Frage scheint vielleicht etwas absurd zu sein, aber ich stehe hier gerade mal wieder vor einem sehr komischen Problem. Ich hab eine DLL aus der ich mehrere Funktionen dynamisch laden möchte. Das Laden scheint an sich keine Probleme zu machen, denn die Funktionsvariablen hab später alle eine Adresse und sind nicht nil.
Trotzdem ist es so, dass eine Funktion beim statischen Aufruf wunderbar läuft, aber beim dynamischen Aufruf mit gleichen Parametern einen Fehler (FILE_NOT_FOUND) zurückgibt. Ich hab hier mal die wichtigsten Codestellen rausgeschrieben, obwohl die warscheinlich bei der Lösung des Problems nicht weiterhelfen können: 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31:
| const stoOpenFileExIndex = $10C;
type TFNStormOpenFileEx = function (hMPQ: THandle; lpFileName: LPCSTR; dwSearchScope: DWORD; hFile: PHandle): BOOL; stdcall;
function SFileOpenFileEx(hMPQ: THandle; lpFileName: LPCSTR; dwSearchScope: DWORD; hFile: PHandle): BOOL; stdcall; external 'storm.dll' index stoOpenFileExIndex;
var SOpenFileEx: TFNStormOpenFileEx; hLib: THandle; begin hLib := LoadLibrary(PATH_TO_DLL); if hLib <> 0 then begin @SOpenFileEx := GetProcAddress(hLib, PChar(MakeLong(stoOpenFileExIndex, 0))); if Assigned(@SOpenFileEx) then SOpenFileEx(mit_selben_Parametern_wie_statische_Dll_aufrufen); end; FreeLibrary(hLib); end; | Ist es möglich Methoden zu schreiben, die man nur statisch Aufrufen kann? Auf welche Dinge muss man insbesondere Achten, wenn man DLLs dynamisch lädt? Hat jemand eine Idee?
Vielen Dank,
Hape! Moderiert von Tino: Topic aus Sonstiges verschoben am Mi 17.11.2004 um 10:41
_________________ Manche antworten um ihren Beitragszähler zu erhöhen, andere um zu Helfen.
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Do 11.11.04 23:28
Naja, du kannst ja mal gucken, ob du den Funktionsindex wirklich korrekt übergibst. Mir kommen Zeile 22 und 23 irgendwie suspekt vor.
Delphi-Quelltext 1:
| GetProcAddress(hLib, PChar(MakeLong(stoOpenFileExIndex, 0))) |
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
wulfskin 
      
Beiträge: 1349
Erhaltene Danke: 1
Win XP
D5 Pers (SSL), D2005 Pro, C, C#
|
Verfasst: Do 11.11.04 23:41
Hallo Ben,
danke, aber ich denke schon das das so stimmt. | PSDK hat folgendes geschrieben: | | If this parameter is an ordinal value, it must be in the low-order word; the high-order word must be zero. |
Den "low-order word" stelle ich mit MakeLong her und typcaste das ganze mit PChar damit der Compiler nix sagt.
Sonst irgendwelche Ideen?
Gruß Hape!
Moderiert von Tino: Tags verbessert.
_________________ Manche antworten um ihren Beitragszähler zu erhöhen, andere um zu Helfen.
|
|
tommie-lie
      
Beiträge: 4373
Ubuntu 7.10 "Gutsy Gibbon"
|
Verfasst: Do 11.11.04 23:43
_________________ Your computer is designed to become slower and more unreliable over time, so you have to upgrade. But if you'd like some false hope, I can tell you how to defragment your disk. - Dilbert
|
|
wulfskin 
      
Beiträge: 1349
Erhaltene Danke: 1
Win XP
D5 Pers (SSL), D2005 Pro, C, C#
|
Verfasst: Do 11.11.04 23:56
Ums mit einem Satz vom Sinnlostelefon auszudrücken: "Das hab ich alles!"
Komisch, komisch.
_________________ Manche antworten um ihren Beitragszähler zu erhöhen, andere um zu Helfen.
|
|
tommie-lie
      
Beiträge: 4373
Ubuntu 7.10 "Gutsy Gibbon"
|
Verfasst: Fr 12.11.04 00:02
| wulfskin hat folgendes geschrieben: | Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| function SFileOpenFileEx(hMPQ: THandle; lpFileName: LPCSTR; dwSearchScope: DWORD; hFile: PHandle): BOOL; stdcall; external 'storm.dll' index stoOpenFileExIndex;
FreeLibrary(hLib); end; | |
_________________ Your computer is designed to become slower and more unreliable over time, so you have to upgrade. But if you'd like some false hope, I can tell you how to defragment your disk. - Dilbert
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Fr 12.11.04 00:03
Weder die DP noch Assarbad hatten das mit dem Laden per Index erklärt oder ich finde dazu nichts.
Versuch aber mal Pointer(stoOpenFileExIndex)
Hab jetzt aber nichts da gehabt zum Testen.
Falls die D5Pers das hat: Guck dir mal im CPU-Fenster (Ansicht\Debug-Fenster\CPU) die Source-Abschnitte zum aufruf der statisch geladenen Funktion und den der dynamisch geladenen Funktion an. Schreib die beiden möglichst in die gleiche Routine, da sich die Aufrufe dann von den Parameter-Zugriffen identisch verhalten (sollten). ASM-Surce dann mal hier posten, ich nehm ihn dann mal auseinander 
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
Sprint
      
Beiträge: 849
|
Verfasst: Fr 12.11.04 00:04
Was soll "Assigned(@SOpenFileEx)" das sein? Richtig wäre doch wohl ohne @? Oder?
Unter D7 muss das nicht so "@SOpenFileEx := GetProcAddress". Kannst ja mal ausprobieren ob das mit D5 auch geht.
_________________ Ciao, Sprint.
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Fr 12.11.04 00:13
@Sprint: Das @ bei GetProcAddress ist richtig.
Bei Assigned müsste ich gucken, dort ging es aber glaube wegzulassen.
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
Sprint
      
Beiträge: 849
|
Verfasst: Fr 12.11.04 00:32
@BenBE: Hab kein D5 installiert, sonst hätte ich es ausprobiert.
_________________ Ciao, Sprint.
|
|
wulfskin 
      
Beiträge: 1349
Erhaltene Danke: 1
Win XP
D5 Pers (SSL), D2005 Pro, C, C#
|
Verfasst: Fr 12.11.04 13:35
Hallo Ben,
leider hat es mit dem Pointer Typcast genauso wenig geklappt. Eigentlich denke ich auch, dass die Funktion korrekt dynamisch geladen wird, da der Funktionszeiger ja sonst auf nil zeigen sollte.
Ich hab dir jetzt mal den ASM-Code des Aufrufs rauskopiert, obwohl ich da auch nix ungewöhnliches erkennen kann  : Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| lea eax,[ebp-$20] push eax push $00 push $004d32c mov eax,[ebp-$1c] push eax call SFileOpenFileEx
lea eax,[ebp-$20] push eax push $00 push $004cd32c mov eax,[ebp-$1c] push eax call dword ptr | @tommie-lie: Ich habe mir mal beide Adressen durchgelesen. Es liegt nicht an der Freigabe, da die erst ganz am Schluss kommt. Und das Tutorial von Asserbad habe ich auch schon durchgearbeitet, brachte mir aber leider keine neuen Erkenntnisse.
Danke für Eure Hilfe,
gruß Hape!
_________________ Manche antworten um ihren Beitragszähler zu erhöhen, andere um zu Helfen.
|
|
Sprint
      
Beiträge: 849
|
Verfasst: Fr 12.11.04 13:47
Wenn ich mir diese www.campaigncreation...e_mopaq/chapter3.htm zu SFileOpenFileEx durchlese, dann musst du doch dein vierten Parameter mit var lphFile: THandle oder mit lphFile: PHandle deklarieren.
_________________ Ciao, Sprint.
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Fr 12.11.04 14:07
Das mit dem Handle ist wirklich eine Sache, was noch theoretisch sein könnte. Das sollte man bei APIs immer mit beachten.
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
Sprint
      
Beiträge: 849
|
Verfasst: Fr 12.11.04 14:09
In der MPQ API Library 2.0 ist die Funktion in C/C++ so deklariert.
Quelltext 1:
| BOOL LMPQAPI WINAPI SFileOpenFileEx(MPQHANDLE hMPQ, LPCSTR lpFileName, DWORD dwFlags, MPQHANDLE *hFile); |
Jetzt weiß du ja, wo du ansetzen musst.
_________________ Ciao, Sprint.
|
|
wulfskin 
      
Beiträge: 1349
Erhaltene Danke: 1
Win XP
D5 Pers (SSL), D2005 Pro, C, C#
|
Verfasst: Fr 12.11.04 14:25
| Sprint hat folgendes geschrieben: | In der MPQ API Library 2.0 ist die Funktion in C/C++ so deklariert.
Quelltext 1:
| BOOL LMPQAPI WINAPI SFileOpenFileEx(MPQHANDLE hMPQ, LPCSTR lpFileName, DWORD dwFlags, MPQHANDLE *hFile); |
Jetzt weiß du ja, wo du ansetzen musst. |
Mhhh...liest du eigentlich meine Beiträge? Meine Funktionsdeklaration ist doch völlig identisch!?
_________________ Manche antworten um ihren Beitragszähler zu erhöhen, andere um zu Helfen.
|
|
wulfskin 
      
Beiträge: 1349
Erhaltene Danke: 1
Win XP
D5 Pers (SSL), D2005 Pro, C, C#
|
Verfasst: Mo 15.11.04 22:24
Ich habe nun mal die DLL in mein Arbeitsverzeichnis reinkopiert und sie statisch mit dem Pfad 'storm.dll' geladen.
Komischweise geht es dann auch nicht mehr, dass heisst, es muss irgendetwas mit dem Arbeitsverzeichnis zu tun haben. Ich habe es schon mit SetCurrentDir versucht, dass hat aber nichts geholfen.
Hat noch jemand eine Idee?
Viele Grüße,
Hans-Peter
_________________ Manche antworten um ihren Beitragszähler zu erhöhen, andere um zu Helfen.
|
|
Johannes Maier
      
Beiträge: 173
Win XP
D7 Prof
|
Verfasst: So 21.11.04 11:57
Was für Werte werden denn später an SOpenFileEx() übergeben? Wenn ich irgendwelche erfundenen Werte eingebe, dann bekomme ich zumindest keine Fehlermeldung ...
Vll. liegt es daran, dass einfach lpFileName nicht gefunden wird?
Kenn mich da auch nicht so aus, aber was macht dieses MakeLong(stoOpenFileExIndex, 0)?
Btw: Ist das nicht eine DLL von WarCraft III? 
_________________ MfG
Johannes ehem. jbmaier
|
|
wulfskin 
      
Beiträge: 1349
Erhaltene Danke: 1
Win XP
D5 Pers (SSL), D2005 Pro, C, C#
|
Verfasst: So 21.11.04 13:04
| Johannes Maier hat folgendes geschrieben: | Was für Werte werden denn später an SOpenFileEx() übergeben? Wenn ich irgendwelche erfundenen Werte eingebe, dann bekomme ich zumindest keine Fehlermeldung ...
Vll. liegt es daran, dass einfach lpFileName nicht gefunden wird?
Kenn mich da auch nicht so aus, aber was macht dieses MakeLong(stoOpenFileExIndex, 0)?
Btw: Ist das nicht eine DLL von WarCraft III?  |
Hallo Johannes,
es liegt weder an meiner "Übersetzung" der Funktion noch an den übergebenen Parameter. Ich habe jetzt auf einer anderen Seite eine Bestätigung für meine Vermutung gefunden: Dynamisches Laden dieser DLL ist gar nicht möglich. Die DLL ist nämlich durch komplizierte interne Mechanismen geschützt, so dass man sie nur statisch laden kann.
Leider ist statisches Laden für mich nicht möglich, da ich schliesslich nicht weiss, wohin der Benutzer das Programm installieren wird.
Auch eine DLL die im Warcraft III-Verzeichnis liegt und diese statisch aufruft hat für mich nicht geklappt, dass heisst ich werde diese DLL wohl nicht benutzen können.
Achja, es ist eine Warcraft III DLL, die für das entpacken der MPQ-Dateien zuständig ist. Ich war gerade dabei einen "Replay Explorer" zu programmieren, werde das Programm aber wohl aus diesem Grund aufgeben  !
Danke für eure Hilfe,
Hape!
_________________ Manche antworten um ihren Beitragszähler zu erhöhen, andere um zu Helfen.
|
|
|