Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Fehler, wenn Procedure aus DLL ausgeführt wird, sonst nicht (https://www.delphipraxis.net/39192-fehler-wenn-procedure-aus-dll-ausgefuehrt-wird-sonst-nicht.html)

Nogge 30. Jan 2005 09:48


Fehler, wenn Procedure aus DLL ausgeführt wird, sonst nicht
 
Hallo Community,
Ich habe hier eine Procedure, die ich aus einer eigenen DLL ausführe:
Code:
procedure SavePLS(Filename: String; Listbox:TListbox; PathList:TStringList);
 external 'DLL_Name.dll';
[...]
Procedure SavePLS(Filename: String; Listbox:TListbox; Pathlist:TStringList);
Const NumItems = 'NumberOfEntries';
      Section = 'Playlist';
var sav:TiniFile; i,Total:Integer; F:TextFile; Buffer:String;
begin
  if not DirectoryExists(ExtractFilePath(FileName)) then exit;
 
  if ExtractFileExt(FileName)='.pls' then
  begin
    sav:=TiniFile.Create(Filename);
    try
      Total:=Pathlist.Count;
      if Total>0 then
      begin
        sav.WriteInteger(Section,NumItems,Total);
        sav.WriteInteger(Section,'Version',2);
        for i:=0 to Total-1 do
        begin
          sav.WriteString(Section,'File'+IntToStr(i+1),Pathlist.Strings[i]);
          sav.WriteString(Section,'Title'+IntToStr(i+1),Listbox.Items.Strings[i]);
          //Ini.WriteInteger(Section,'Length' + IntToStr(i+1),Integer(FTime.Objects[i]));
        end;
      end;
    finally
      sav.Free;
    end;
  end;

  if ExtractFileExt(FileName)='.m3u' then
  begin
    try
      AssignFile(F,Filename);
      Rewrite(F);
      Writeln(F,'#EXTM3U');
      for i:=0 to PathList.Count-1 do
      begin
        Buffer:=Format('#EXTINF:%d,%s',[-1 {Time},PathList.Strings[i]]);
        WriteLn(F,Buffer);
        WriteLn(F,Listbox.Items.Strings[i]);
      end;
    finally
      CloseFile(F);
    end;
  end;
end;
Wenn ich diese Procedure beim OnClose-Ereignis ausführe, erscheint eine Fehlermeldung...ungefähr diese: 'Access Violation at Address [...], Write of Address [...]'. Nachdem ich die Procedure in mein Programm eingefügt und diese von dort aus ausgeführt hatte, erhielt ich keine Fehlermeldung mehr.
Könnt Ihr mir helfen, das Problem zu verstehen bzw. zu lösen?

mfg Nogge

stefan2005 30. Jan 2005 10:15

Re: Fehler, wenn Procedure aus DLL ausgeführt wird, sonst ni
 
hi,
der Fehler liegt dort, dass du als Übergabe-Parameter einen String hast.
Für Strings musst du eine zusätzliche Unit (ShareLib oder so) von Borland einbinden.
Mach es deshalb lieber mit einem PChar oder Array of Char.

cu,
stefan2005

Nogge 30. Jan 2005 10:31

Re: Fehler, wenn Procedure aus DLL ausgeführt wird, sonst ni
 
d.h ich sollte so deklarieren: FileName: PChar ? Hab ich gerade gemacht, nur kommt der selbe Fehler schon wieder.

FreeStyle 30. Jan 2005 10:48

Re: Fehler, wenn Procedure aus DLL ausgeführt wird, sonst ni
 
Dann versuche es folgendermaßen:

füge Deiner Anwendung die Unit 'ShareMem' hinzu und liefere
mit dem Programm die BORLNDMM.DLL mit aus.

Delphi-Quellcode:
{ Wichtiger Hinweis zur DLL-Speicherverwaltung: ShareMem muss sich in der
  ersten Unit der unit-Klausel der Bibliothek und des Projekts befinden (Projekt-
  Quelltext anzeigen), falls die DLL Prozeduren oder Funktionen exportiert, die
  Strings als Parameter oder Funktionsergebnisse übergeben. Das gilt für alle
  Strings, die von oder an die DLL übergeben werden -- sogar für diejenigen, die
  sich in Records und Klassen befinden. Sharemem ist die Schnittstellen-Unit zur
  Verwaltungs-DLL für gemeinsame Speicherzugriffe, BORLNDMM.DLL.
  Um die Verwendung von BORLNDMM.DLL zu vermeiden, können Sie String-
  Informationen als PChar- oder ShortString-Parameter übergeben. }
Viele Grüße

FreeStyle

Nogge 30. Jan 2005 11:12

Re: Fehler, wenn Procedure aus DLL ausgeführt wird, sonst ni
 
Was meinst du mit
Zitat:

Liefere mit dem Programm die BORLNDMM.DLL mit aus.
?
Ich habe jetzt jedenfalls in der DLL und in meiner MainUnit bei "uses" ShareMem hinzugefügt, was aber in keinster Weise etwas brachte. Vllt würde mir ein kleines Beispiel von dir helfen...^^

Sprint 30. Jan 2005 11:16

Re: Fehler, wenn Procedure aus DLL ausgeführt wird, sonst ni
 
Zitat:

Zitat von Nogge
Ich habe jetzt jedenfalls in der DLL und in meiner MainUnit bei "uses" ShareMem hinzugefügt, was aber in keinster Weise etwas brachte. Vllt würde mir ein kleines Beispiel von dir helfen...^^

Das Problem ist deine ListBox.

Nogge 30. Jan 2005 11:25

Re: Fehler, wenn Procedure aus DLL ausgeführt wird, sonst ni
 
Und was sollte ich deiner Meinung nach jetzt verändern?

Sprint 30. Jan 2005 12:51

Re: Fehler, wenn Procedure aus DLL ausgeführt wird, sonst ni
 
Was steht denn in der ListBox drin? Die Dateinamen? Übergib deiner Funktion lieber einen String in Form eines PChar und splitte den wieder auf. Damit wenig Fehler auftreten können, würde ich auf die Übergabe von Klassen grundsätzlich verzichten.

Ungetestet:
Delphi-Quellcode:
procedure SavePLS(FileName, S1, S2: PChar); stdcall;
// Procedure SavePLS(Filename: String; Listbox:TListbox; Pathlist:TStringList);
Const NumItems = 'NumberOfEntries';
      Section = 'Playlist';
var sav:TiniFile; i,Total:Integer; F:TextFile; Buffer:String;
  PathList: TStringList;
  ListBox: TStringList;
begin

  PathList := TStringList.Create;
  ListBox := TStringList.Create;
  try

    PathList.CommaText := S1;
    ListBox.CommaText := S2;

    if not DirectoryExists(ExtractFilePath(FileName)) then exit;

    if ExtractFileExt(FileName)='.pls' then
    begin
      sav:=TiniFile.Create(Filename);
      try
        Total:=Pathlist.Count;
        if Total>0 then
        begin
          sav.WriteInteger(Section,NumItems,Total);
          sav.WriteInteger(Section,'Version',2);
          for i:=0 to Total-1 do
          begin
            sav.WriteString(Section,'File'+IntToStr(i+1),Pathlist.Strings[i]);
            // sav.WriteString(Section,'Title'+IntToStr(i+1),Listbox.Items.Strings[i]);
            sav.WriteString(Section,'Title'+IntToStr(i+1),Listbox.Strings[i]);
          end;
        end;
      finally
        sav.Free;
      end;
    end;

    if ExtractFileExt(FileName)='.m3u' then
    begin
      try
        AssignFile(F,Filename);
        Rewrite(F);
        Writeln(F,'#EXTM3U');
        for i:=0 to PathList.Count-1 do
        begin
          Buffer:=Format('#EXTINF:%d,%s',[-1 {Time},PathList.Strings[i]]);
          WriteLn(F,Buffer);
          // WriteLn(F,Listbox.Items.Strings[i]);
          WriteLn(F,Listbox.Strings[i]);
        end;
      finally
        CloseFile(F);
      end;
    end;

  finally
    ListBox.Free;
    PathList.Free;
  end;

end;
Aufrufen kannst du es dann so:
Delphi-Quellcode:
SavePLS(PChar(FileName), PChar(ListBox1.Items.CommaText), PChar(PathList.CommaText));

Nogge 30. Jan 2005 19:54

Re: Fehler, wenn Procedure aus DLL ausgeführt wird, sonst ni
 
Jo, Danke...So funktioniert es jetzt.

[Edit] Was bedeutet "stdcall;" hinter der Procedure? [/Edit]


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:18 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz