Autor Beitrag
muuuh
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Do 16.02.06 21:09 
Deklaration in der aufrufenden .exe:
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:
function check_ini(pfad: string): boolean; stdcall;
external eb_ini_dll;

function _check_ini(pfad: string):boolean;
var
 dll : string;
 Handle: THandle;
begin
dll := eb_ini_dll;
if FileExists(dll) then
begin
  Handle:=LoadLibrary(PChar(ExtractFilePath(ParamStr(0))+dll));
  if Handle <> 0 then begin
    if GetProcAddress(Handle, 'check_ini') <> nil then begin
check_ini(pfad);
//result:=true;
    end;
FreeLibrary(Handle);
end
else
begin
ShowMessage(dll+' konnte nicht gefunden werden.');
end;
FreeLibrary(Handle);
result := true;
end;
end;
//-------------------------------------------->
Button
...
_check_ini('c:\sabber.cfg');

In der dll aufgerufende Funktionen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
function check_ini(datei: string): boolean; stdcall;
var
pIni : Tinifile;
begin
pIni := Tinifile.Create(datei);
try
pIni.WriteString('programm','name','TestProgramm');
pIni.WriteString('programm','build','0815');
...
finally
pIni.Free;
end;


Wenn ich das Programm nun über den Shell Aufruf z.Bsp.: test.exe c:\temp
aufrufe crashed das entladen der dll.

Wenn ich das Programm normal über den Explorer starte funktioniert´s ohne Probleme ????????

Moderiert von user profile iconGausi: Beitragsformatierung überarbeitet.
digi_c
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1905

W98, XP
D7 PE, Lazarus, WinAVR
BeitragVerfasst: Do 16.02.06 21:38 
Meinst du es hagelt Fehler beim Entladen der DLL oder der INI?

Bitte formatiere deinen Code, das ist ja ein Grauß :(
Blackheart666
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2195

XP
D3Prof, D6Pers.
BeitragVerfasst: Do 16.02.06 23:30 
Ich kann Mir nicht denken das man so etwas überhaupt zum Laufen bringt !
Geschweige denn vom Sinn des Ganzem.
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Do 16.02.06 23:34 
Hast du den fetten Kommentar gelsen, der von Delphi in den Unitheader geschrieben wird, wenn man eine DLL mit dem DLL-wizard ertellt? Ansonsten solltest du dir mal das DLL Tutorial durchlesen: www.michael-puff.de/...hi/Importe/Assarbad/
muuuh
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mo 20.02.06 13:41 
Titel: Ich versuch´s mal mit PChar, so wie in BD Help steht ??
Wo ist der Fehler ? Die Funktionen werden nach der uses Klausel eingesetzt. Wie gesagt: Das Problem kommt erst dann zum tragen, wenn ich dem Programm einen anderen Parameter mitgebe.

Wie könnte ich denn z.Bsp. in der OnCloseRequest Funktion noch rausbekommen, welche Dlls noch geshared sind, um Sie danach zu entladen ???
muuuh
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mo 20.02.06 13:50 
Titel: Apropo, danke Michael für den netten Tip ?
Und bitte verschwendet deine Zeit nicht damit, deine "bad vibrations" hier los zu werden, BH ! - P-) -
AndyB
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1173
Erhaltene Danke: 14


RAD Studio XE2
BeitragVerfasst: Mo 20.02.06 13:58 
Wenn du check_ini bereits über external einbindest, dann macht der ganze LoadLibrary/GetProcAddress Code überhaupt keinen Sinn mehr. Denn wenn Windows die DLL beim Laden nicht findet, kommt die Standard-Windows-Fehlermeldung über nicht gefundene Symbole in einer DLL.
Den ganzen LoadLibrary/GetProcAddress Code kannst du also schon mal streichen.

Der nächste Fehler ist, dass du einen String an die DLL übergibst. Wie Luckie bereits schrieb, solltest du dir mal den Kommentar, den Delphi in der .dpr Datei hinterlassen hat, mal genau durchlesen. Wenn du das getan hast, wirst du feststellen, dass man keine Strings oder dynamischen Arrays direkt oder indirekt (Records, Klassen) an eine DLL übergeben soll, weil der Speichermanager der Anwendung nicht der Speichermanager der DLL ist, und man nie genau weiß, welcher der beiden Speichermanager den String nun allokiert oder freigegeben hat.
Das mit dem ParamStr() lässt sich dadurch erklären, dass durch Zufall der von der Anwendung reservierte, aber von der DLL freigegebene String nicht sofort überschrieben wird. Das ist aber reiner Zufall und kann sich sehr schnell ändern.

Wenn du Strings übergeben willst, gibt es drei Möglichkeiten:
  • PChar statt String benutzen
  • Die ShareMem Unit, wie es im Delphi-DLL-Kommentar steht, nutzen
  • Die DLL und die EXE an das RTL-Package binden (Projekt-Optionen/Packages/Mit Laufzeitpackages kompilieren).

_________________
Ist Zeit wirklich Geld?
AndyB
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1173
Erhaltene Danke: 14


RAD Studio XE2
BeitragVerfasst: Mo 20.02.06 14:04 
Übrigens: Zu jedem LoadLibrary gehört normalerweise ein FreeLibrary. Und nicht wie bei dir 2x FreeLibrary. DLLs besutzen einen Referenzzähler. Dieser wird bei LoadLibrary um eins erhöht, und bei FreeLibrary verringert. Ist dieser Referenzzähler Null, so wird die DLL aus dem Speicher geladen. Dein doppeltes FreeLibrary entlädt also die DLL und jeglicher Zugriff auf die DLL (in deinem Fall ein check_ini Aufruf) endet mit einer Schutzverletzung.

_________________
Ist Zeit wirklich Geld?
muuuh
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mo 20.02.06 18:48 
Titel: Darauf wäre ich ja garnicht gekommen !!!
Also, erstmal danke an alle, die mir geholfen haben.

Zur Info: Die externen Funktionsdeklarationen sind korrekt gewesen.

Der Fehler war folgender: Ich hatte QForms und nicht Forms über die uses
liste included.

Ich geb zu, daß ich noch nicht genau differenzieren kann, in wie weit sich
QForms von den Forms unterscheiden (ist schon klar, im Zweifel reinlesen).

Wie dem auch sein --------> Fettes Dankeschön <------------

Euer dlln00b