Autor Beitrag
Wolle92
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 1296

Windows Vista Home Premium
Delphi 7 PE, Delphi 7 Portable, bald C++ & DirectX
BeitragVerfasst: Sa 25.08.07 10:20 
Hallo,
immer wenn ich funktionen aus einer dynamischen DLL benutzen will,
bekomme ich eine EAccessViolation...

Typen:
ausblenden Delphi-Quelltext
1:
2:
type Tencode = function(text: String): String;
type Tdecode = function(text: String): String;


Variablen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
var
  Form1: TForm1;
  encode: Tencode;
  decode: Tdecode;
  handle1: THandle;


DLL-Einbindung:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
procedure TForm1.FormCreate(Sender: TObject);
begin
  handle1 := LoadLibrary(PChar(ExtractFilePath(Application.ExeName)+'crypt.dll'));
  if handle = 0 then
  begin
    ShowMessage('DLL crypt.dll konnte nicht geladen werden!');
    Form1.Close;
  end;
  encode := GetProcAddress(handle, 'encode');
  decode := GetProcAddress(handle, 'decode');
end;


Aufruf der Funktionen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
procedure TForm1.Button1Click(Sender: TObject);
begin
  Label1.Caption := '';
  Label1.Caption := encode(Edit1.Text);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  Label2.Caption := '';
  Label2.Caption := decode(Label1.Caption);
end;
GTA-Place
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
EE-Regisseur
Beiträge: 5248
Erhaltene Danke: 2

WIN XP, IE 7, FF 2.0
Delphi 7, Lazarus
BeitragVerfasst: Sa 25.08.07 10:51 
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
procedure TForm1.FormCreate(Sender: TObject);
begin
  handle1 := LoadLibrary(PChar(ExtractFilePath(Application.ExeName)+'crypt.dll'));
  if handle = 0 then
  begin
    ShowMessage('DLL crypt.dll konnte nicht geladen werden!');
    Form1.Close;
  end;
  encode := GetProcAddress(handle, 'encode');
  decode := GetProcAddress(handle, 'decode');
end;


Ob es wohl daran liegt?

_________________
"Wer Ego-Shooter Killerspiele nennt, muss konsequenterweise jeden Horrorstreifen als Killerfilm bezeichnen." (Zeit.de)
Wolle92 Threadstarter
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 1296

Windows Vista Home Premium
Delphi 7 PE, Delphi 7 Portable, bald C++ & DirectX
BeitragVerfasst: So 26.08.07 16:44 
Titel: Re: Funktionen aus dynamisch eingebundener DLL aufrufen = Fe
ne, die varaible heißt ja handle1
aber da ist der Fehler:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
procedure TForm1.FormCreate(Sender: TObject);
begin
  handle1 := LoadLibrary(PChar(ExtractFilePath(Application.ExeName)+'crypt.dll'));
  if handle = 0 then
  begin
    ShowMessage('DLL crypt.dll konnte nicht geladen werden!');
    Form1.Close;
  end;
  encode := GetProcAddress(handle, 'encode');
  decode := GetProcAddress(handle, 'decode');
end;

Da fehlt die 1
GTA-Place
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
EE-Regisseur
Beiträge: 5248
Erhaltene Danke: 2

WIN XP, IE 7, FF 2.0
Delphi 7, Lazarus
BeitragVerfasst: So 26.08.07 16:46 
Ich hab ja nicht gesagt, dass der Fehler bei der 1 liegt, sondern dass die 1 bei den anderen fehlt. Übrigens auch hier:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
procedure TForm1.FormCreate(Sender: TObject);  
begin  
  handle1 := LoadLibrary(PChar(ExtractFilePath(Application.ExeName)+'crypt.dll'));  
  if handle = 0 then  
  begin  
    ShowMessage('DLL crypt.dll konnte nicht geladen werden!');  
    Form1.Close;  
  end;  
  encode := GetProcAddress(handle, 'encode');  
  decode := GetProcAddress(handle, 'decode');  
end;

_________________
"Wer Ego-Shooter Killerspiele nennt, muss konsequenterweise jeden Horrorstreifen als Killerfilm bezeichnen." (Zeit.de)
Wolle92 Threadstarter
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 1296

Windows Vista Home Premium
Delphi 7 PE, Delphi 7 Portable, bald C++ & DirectX
BeitragVerfasst: So 26.08.07 17:14 
Hmm, hab jetzt alles auf handle1 geändert, und bekomme EInvalidPointer als Dank...
Wolle92 Threadstarter
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 1296

Windows Vista Home Premium
Delphi 7 PE, Delphi 7 Portable, bald C++ & DirectX
BeitragVerfasst: So 26.08.07 18:51 
Hab grad etwas sehr interessantes herausgefunden:
Wenn ich das "Edit1" in dem edit-feld stehen lasse, dannn läuft es problemlos (aber auch nur einmal)...
Wenn ich den Text ändere, und der neue Text genausoviele Zeichen wie "Edit1" hat, klappts auch (nur einmal)...
Wenn ich erst "Edit1" benutze und dann in einen genauso langen Text ändere, gibts auch nen Error bei zweiten mal...

Wenn ich das kodierte "Edit1" oder eben ein anderes, gleichlanges Wort, dekodiere, kann ich das sooft machen, wie ich lust zu habe...

Und außerdem:
Wenn ich die Funktionen lokal deklariere, läuft alles problemlos, also kann es kein Problem in den Funktionen sein...
auch beim statischen Einbinden gibts die gleichen Probleme...
Beim Schliessen des Fensters gibbts noch eine EAccessViolation oben drauf...
ausblenden Delphi-Quelltext
1:
2:
3:
4:
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  FreeLibrary(handle1);
end;


Merke: Ich will das unbedingt mit der DLL machen, nicht lokal... einfach ums können zu können...
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: So 26.08.07 20:19 
1. Warum ist das DLL-Handle keine lokale Variable?
2. Warum wertes du nit GetLastError aus, um eine aussagekräftige Fehlermeldung zu bekommen?
3. Wo ist die Fehlerbehandlung bei getProcAddress?
4. Ein Beispiel, wie es richtig ist:
ausblenden 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:
 type
  TShellexecute = function(hWnd: HWND; Operation, FileName, Parameters,
    Directory: PChar; ShowCmd: Integer): HINST; stdcall;

procedure TForm1.Button1Click(Sender: TObject);
var
  hLib: cardinal;
  MyShellExecute: TShellexecute;
begin
  hLib := LoadLibrary('shell32.dll');
  if hLib <> 0 then
  begin
    @MyShellexecute := GetProcAddress(hLib, 'ShellExecuteA');
    if not Assigned(MyShellexecute) then
    begin
      RaiseLastOSError;
      exit;
    end;
  end
  else
  begin
    RaiseLastOSError;
    exit;
  end;
  MyShellexecute(Form1.Handle, 'open', 'Notepad.exe', nil, nil, SW_NORMAL);
end;


5. Du weißt wie man Strings an Funktionen in DLLs übergibt und zurückgeben lässt?
Wolle92 Threadstarter
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 1296

Windows Vista Home Premium
Delphi 7 PE, Delphi 7 Portable, bald C++ & DirectX
BeitragVerfasst: Mo 27.08.07 13:59 
1. Ist es doch...
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
var
  Form1: TForm1;
  encode: Tencode;
  decode: Tdecode;
  handle1: THandle;

2.Noch nicht drauf gekommen
3.Noch nicht eingebaut, behebt den Fehler aber auch nicht
4.Das Beispiel eventuell anzupassen, wäre ja hilfreicher gewesen, aber so gehts auch
5.Wenn es, so wie es im ersten Post von mir steht, falsch ist, kannst du es auch gleich sagen...

Außerdem gibts die gleichen Fehler ja bei statischer einbindung...
ausblenden Delphi-Quelltext
1:
2:
function encode(text: String): String; external 'D:\Program files\Borland\Delphi7\Projects\crypt.dll' name 'encode';
function decode(text: String): String; external 'D:\Program files\Borland\Delphi7\Projects\crypt.dll' name 'decode';
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mo 27.08.07 14:53 
user profile iconWolle92 hat folgendes geschrieben:
1. Ist es doch...
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
var
  Form1: TForm1;
  encode: Tencode;
  decode: Tdecode;
  handle1: THandle;

Wo ist denn das eine lokale Variable?

Zitat:

2.Noch nicht drauf gekommen
3.Noch nicht eingebaut, behebt den Fehler aber auch nicht

Könnte aber helfen den Fehler zu finden.

Zitat:
4.Das Beispiel eventuell anzupassen, wäre ja hilfreicher gewesen, aber so gehts auch

Das solltest du dir selber anpassen können.

Zitat:
5.Wenn es, so wie es im ersten Post von mir steht, falsch ist, kannst du es auch gleich sagen...

Ich weiß ja nicht, ob es falsch ist, je nach dem was du gemacht hast. Wenn du im Projket und in der DLL ShareMem eingebunden hast, ist nichts falsch. Deswegen frage ich, ob du weißt wie man Strings an DLL-Funktionen übergibt.
Wolle92 Threadstarter
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 1296

Windows Vista Home Premium
Delphi 7 PE, Delphi 7 Portable, bald C++ & DirectX
BeitragVerfasst: Mo 27.08.07 15:00 
1. "handle1: THandle" ist das Handle für die DLL...
4. Dann sach ich mal, dass ich es nicht weiß... wie shareMem einbinden?
Lossy eX
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1048
Erhaltene Danke: 4



BeitragVerfasst: Mo 27.08.07 15:05 
Ist das eine DLL von dir?

Wenn ja wäre es wohl besser wenn du expliziet Aufrufkonvention angibst (stdcall oder cdecl). Wenn das keine DLL von dir ist dann solltest du dir mal die Spezifikation davon anschauen und prüfen was dort für eine Konvention benutzt wird. Denn "läuft es problemlos (aber auch nur einmal)" klingt für mich fast so als ob du dir etwas auf dem Stack zerschießen würdest. Und wenn du eine Methode die Parameter so übergibt und die Andere diese anders erwartet passiert so etwas gerne mal.

_________________
Nur die Menschheit ist arrogant genug, um zu glauben sie sei die einzige intelligente Lebensform im All. Wo nicht mal das nachhaltig bewiesen wurde.
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mo 27.08.07 15:06 
user profile iconWolle92 hat folgendes geschrieben:
1. "handle1: THandle" ist das Handle für die DLL...

Ich weiß, aber wo ist die denn lokal deklariert? LOkal heißt innerhalb einer Prozedur oder Funktion und nicht global in der ganzen Unit.

Zitat:
4. Dann sach ich mal, dass ich es nicht weiß... wie shareMem einbinden?

Da kommen wir der Sache doch schon mal näher. Häätest du das Projekt für die DLL mit dem Assistenten angelegt, hättest du dir nur mal den Kommentar am Anfang durchlesen müssen.

Ansonsten hier: www.michael-puff.de/..._07_String_DLL.shtml und hier www.michael-puff.de/...hi/Importe/Assarbad/ mal gucken.
Wolle92 Threadstarter
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 1296

Windows Vista Home Premium
Delphi 7 PE, Delphi 7 Portable, bald C++ & DirectX
BeitragVerfasst: Mo 27.08.07 15:23 
danke
Allerdings gibts jetzt immernoch eine EInvalidPointer-Message beim Schliessen des Fensters, es gibt aber kein FormClose mehr

Edit: Hat sich erledigt, hatte ShareMem in der uses-Liste der Unit, nicht des Projekts