Autor Beitrag
wulfskin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1349
Erhaltene Danke: 1

Win XP
D5 Pers (SSL), D2005 Pro, C, C#
BeitragVerfasst: 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:
ausblenden volle Höhe Delphi-Quelltext
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;

//Funktionskopf (fürs dynamische Laden)
type
  TFNStormOpenFileEx = function (hMPQ: THandle; lpFileName: LPCSTR;
    dwSearchScope: DWORD; hFile: PHandle): BOOL; stdcall;

//statisch laden (klappt)

function SFileOpenFileEx(hMPQ: THandle; lpFileName: LPCSTR;
  dwSearchScope: DWORD; hFile: PHandle): BOOL; stdcall;
  external 'storm.dll' index stoOpenFileExIndex;

//dynamisch laden
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);
      //Funktion ist nicht nil und wird auch aufgerufen.
      //Jedoch bekomme ich immer nen Fehler FILE_NOT_FOUND und die 
      //Funktion scheitert. Beim statischen klappts.
  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 user profile iconTino: 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: 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.

ausblenden 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1349
Erhaltene Danke: 1

Win XP
D5 Pers (SSL), D2005 Pro, C, C#
BeitragVerfasst: 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 user profile iconTino: Tags verbessert.

_________________
Manche antworten um ihren Beitragszähler zu erhöhen, andere um zu Helfen.
tommie-lie
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 4373

Ubuntu 7.10 "Gutsy Gibbon"

BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1349
Erhaltene Danke: 1

Win XP
D5 Pers (SSL), D2005 Pro, C, C#
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 4373

Ubuntu 7.10 "Gutsy Gibbon"

BeitragVerfasst: Fr 12.11.04 00:02 
wulfskin hat folgendes geschrieben:
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 849



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 849



BeitragVerfasst: Fr 12.11.04 00:32 
@BenBE: Hab kein D5 installiert, sonst hätte ich es ausprobiert.

_________________
Ciao, Sprint.
wulfskin Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1349
Erhaltene Danke: 1

Win XP
D5 Pers (SSL), D2005 Pro, C, C#
BeitragVerfasst: 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 :(:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
//SFileOpenFileEx (Aufruf statisch):
lea eax,[ebp-$20]
push eax
push $00
push $004d32c
mov eax,[ebp-$1c]
push eax
call SFileOpenFileEx

//SOpenFileEx (Aufruf dynamisc)
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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 849



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 849



BeitragVerfasst: Fr 12.11.04 14:09 
In der MPQ API Library 2.0 ist die Funktion in C/C++ so deklariert.
ausblenden 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1349
Erhaltene Danke: 1

Win XP
D5 Pers (SSL), D2005 Pro, C, C#
BeitragVerfasst: 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.
ausblenden 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1349
Erhaltene Danke: 1

Win XP
D5 Pers (SSL), D2005 Pro, C, C#
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 173

Win XP
D7 Prof
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1349
Erhaltene Danke: 1

Win XP
D5 Pers (SSL), D2005 Pro, C, C#
BeitragVerfasst: 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.