AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi DLL laden bringt einen FastMM Fehler (siehe Post #7!)
Thema durchsuchen
Ansicht
Themen-Optionen

DLL laden bringt einen FastMM Fehler (siehe Post #7!)

Ein Thema von schwa226 · begonnen am 11. Okt 2008 · letzter Beitrag vom 18. Okt 2008
Antwort Antwort
schwa226

Registriert seit: 4. Apr 2008
400 Beiträge
 
#1

DLL laden bringt einen FastMM Fehler (siehe Post #7!)

  Alt 11. Okt 2008, 20:11
Hi,

Ich habe ein kleines Problem hier:

In einer DLL gibt es diese Funktion:
Code:
procedure Soft_name (data:pchar; size:integer); stdcall ;export;
begin
  StrLCopy(data, SoftName, size);
end;
Diese DLL binde ich nun so ein:
Code:
TPluginName = procedure (data:pchar; size:integer); stdcall;

  FarProcName: TPluginName;
In meiner Funktion lade ich nun die DLL und suche mir die Funktion.
Code:
var
data : PChar;
begin

  sDLLPath := ExtractFilePath(Application.ExeName) + 'SoftPlug.dll';
  hDLL := LoadLibrary(pChar(sDLLPath));
  if hDLL = 0 then begin
    ShowMessage('DLL konnte nicht geladen werden.');
    Exit;
  end;

  try
    FarProcName := GetProcAddress(hDLL, 'Soft_name');
    if Assigned(FarProcName) then
      FarProcName(data,10);
  except
    ShowMessage('Funktion name der DLL konnte nicht ausgeführt werden.');
  end;
Doch wenn ich durchlaufe scheint es ein Problem mit StrLCopy SoftName->data zu geben.

Wenn ich beim Debuggen in der DLL den Wert von data ändere (mit dem Debugger-Inspector) kann der SoftName auf data kopiert werden. Dann kommt zumindest keine Fehlermeldung in der EXE. Die Variable data ist jedoch trotzdem leer!?

Hab es einmal mit static laden der DLL versucht. Da kommt kein Fehler und ich bekomme einen Wert von der DLL zurück.

Woran kann das liegen?
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#2

Re: Dynamische DLL Funktion bringt nur Fehler

  Alt 11. Okt 2008, 20:37
Zitat:
Wenn ich beim Debuggen in der DLL den Wert von data ändere (mit dem Debugger-Inspector) kann der SoftName auf data kopiert werden.
änderst du wirklich den Wert von data? da data nicht mir var übergeben wird bringt das rein gar nichts. Aber ich glaube du willst auch nicht data ändern sondern das wo data drauf zeigt.
Wenn ich deinen Quelltext so anschaue bist du dir jedoch gar nicht bewusst was du da machst. data ist bei dir ein PChar also einfach ein typisierter Pointer. Diesen lässt du uninitialisiert und übergibst ihn der DLL. Mich wundert es das du keine Warnung bekommst da du mit einer uninitialisierten Variablen arbeitest.
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
Benutzerbild von sx2008
sx2008

Registriert seit: 15. Feb 2008
Ort: Baden-Württemberg
2.332 Beiträge
 
Delphi 2007 Professional
 
#3

Re: Dynamische DLL Funktion bringt nur Fehler

  Alt 11. Okt 2008, 21:01
Du reservierst ja gar keinen Speicher für "data".
probier mal:
Delphi-Quellcode:
var
data : Ansistring; // <== geändert !
begin

  sDLLPath := ExtractFilePath(Application.ExeName) + 'SoftPlug.dll';
  hDLL := LoadLibrary(pChar(sDLLPath));
  if hDLL = 0 then begin
    // Exceptions sind viel besser als ShowMessage + Exit
    raise Exception.Create('DLL Softplug.dll konnte nicht geladen werden.');
  end;

  FarProcName := GetProcAddress(hDLL, 'Soft_name');
  if Assigned(FarProcName) then
  begin
    SetLength(data, 200); // grosszügig Speicher reservieren
    FarProcName(PChar(data), Length(data));
    data := PChar(data); // String verkürzen, bis das erste #0-Zeichen auftaucht
    ShowMessage('data='+data); // data anzeigen
  end
  else
    raise Exception.Create('Funktion Soft_name nicht gefunden');
  Mit Zitat antworten Zitat
schwa226

Registriert seit: 4. Apr 2008
400 Beiträge
 
#4

Re: Dynamische DLL Funktion bringt nur Fehler

  Alt 13. Okt 2008, 08:24
Vielen Dank!

Hab mir schon gedacht das etwas mit dem Speicher reservieren zu tun hat.

Hatte es im Moment so gelöst was mir aber nicht gefällt:
Code:
var
s : ARRAY[0..40] OF CHAR;

begin

p := @s;
..
..
end;
bräuchte nähmlich ein Array von p um mehrere Verschiedene DLL-Namen einlesen zu können.

Werde das mit data : Ansistring; // <== geändert ! einmal versuchen!
Da kann ich dann ja das data : array[0..9] of Ansistring; definieren.

Danke!
  Mit Zitat antworten Zitat
schwa226

Registriert seit: 4. Apr 2008
400 Beiträge
 
#5

Re: Dynamische DLL Funktion bringt nur Fehler

  Alt 14. Okt 2008, 07:46
thx @sx2008
Hab es nun so verwendet und es funktioniert einwandfrei!

Noch eine Frage zu dem DLL-Loading

Ich lade nun externe Plugins mit LoadLibrary von einem Unterordner z.B. C:\Programme\Meine Soft\Plugins\ExternalPlugins

Da die Plugins Ursprünglich für eine andere App geschrieben wurden kann es sein das diese Plugins DLLs von dieser App brauchen. Auch sind sie manchmal so Programiert das sie einfach einen Ordner zurückgehen um dann nach diesen DLLs zu suchen.

Somit müssen diese externen Plugins dann in z.B. C:\Programme\Original App\Plugins ausgeführt werden.

Kann ich also zuerst die Plugins die diese App-DLLs nicht brauchen in meinem Ordner C:\Programme\Meine Soft\Plugins\ExternalPlugins mit LoadLibrary laden.

Um die Plugins in dem C:\Programme\Original App\Plugins Ordner starten zu können muss ich da SetDllDirectory verwenden??
Oder geht das nicht da sich auch dann der Ordner der vorher geladenen DLLs ändert.

Sozusagen so der Ablauf:

SetDllDirectory C:\Programme\Meine Soft\Plugins\ExternalPlugins
LoadLibrary DLL1 in C:\Programme\Meine Soft\Plugins\ExternalPlugins
LoadLibrary DLL2 in C:\Programme\Meine Soft\Plugins\ExternalPlugins
SetDllDirectory C:\Programme\Original App\Plugins
LoadLibrary DLL3 in C:\Programme\Original App\Plugins

Kann das gehen?
Wenn ja wie binde ich SetDllDirectory in meine Unit ein? Gibt es ein Beispiel dazu?
Muss ich da die Kernel32.dll laden und dann die SetDllDirectory Function definieren?

Vielen Dank für Hilfe!
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#6

Re: Dynamische DLL Funktion bringt nur Fehler

  Alt 14. Okt 2008, 09:21
Das sollte funktionieren. Bedenke aber, dass diese Funktionen erst ab Windows XP SP1 zur Verfügung stehen.

Einbinden kannst du es so (ich habe noch die GetDLLDirectory angefügt, falls du sie brauchst)
Musst du nur irgendwo vor dem Aufruf der Funktion definieren.
Delphi-Quellcode:
function SetDLLDirectory(lpPathName:PWideChar):Bool; stdcall;
   external kernel32 name 'SetDllDirectoryW';

function GetDLLDirectory(nBufferLength: DWord; lpBuffer:PWideChar):DWord; stdcall;
   external kernel32 name 'GetDllDirectoryW';
Und hier noch die alte AnsiChar-Version:
Delphi-Quellcode:
function SetDLLDirectory(lpPathName:PAnsiChar):Bool; stdcall;
   external kernel32 name 'SetDllDirectoryA';

function GetDLLDirectory(nBufferLength: DWord; lpBuffer:PAnsiChar):DWord; stdcall;
   external kernel32 name 'GetDllDirectoryA';
Das wäre jetzt statisches Einbinden der Funktionen. Falls du jetzt eine zu alte Windows-Version hat, würde dein Programm nicht starten. Das kannst du nur über dynamisches einbinden verhindern. Das geht direkt so:
Delphi-Quellcode:
type TSetDLLDirectory=function(lpPathName:PWideChar):Bool; stdcall;



var SetDLLDirectory:TSetDLLDirectory;
    lib:hmodule;
begin
  lib:=getmodulehandle('kernel32.dll');
  if lib=0 then
    raise Exception.create('kernel32 nicht geladen');

  SetDLLDirectory:=getprocaddress(lib,'SetDllDirectoryW');
  if not assigned(SetDLLDirectory) then
    raise Exception.create('Der Prozedureinsprungpunkt SetDLLDirectoryW wurde nicht gefunden');

  //Aufruf:
  SetDLLDirectory('x:\yz');
Edit: Verhindern kannst du es nicht. Du kannst es nur abfangen
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
schwa226

Registriert seit: 4. Apr 2008
400 Beiträge
 
#7

Re: Dynamische DLL Funktion bringt nur Fehler

  Alt 17. Okt 2008, 16:25
@sirius: Vielen dank! Funktioniert super! Habe noch einen Windows Version Check eingebunden damit die Fehlersuche leichter wird...

Jetzt hab ich aber ein neues Problem und zwar so neu, da ich noch nie mit FastMM gearbeitet habe.

Ich will ja eine externe DLL Laden. Diese DLL scheint FastMM mitcompiliert zu haben den beim Loadlibray bekomme ich diese Meldung:
http://s3b.directupload.net/images/0...p/q3bvuxtj.jpg
Wenn ich die Applikation dann beende bekomme ich gar nicht schöne Fehlermeldungen (ca 3 STK).

Nach etwas suchen habe ich dann die FastMM gefunden und in meinem Projekt File ganz oben bei den uses angegeben:
Code:
uses
  FastMM4 in 'FastMM4.pas',
  FastMM4Messages in 'FastMM4Messages.pas',
Dann gab es noch keine Verbesserung. Dann habe ich noch in der "FastMM4Options.inc" das aktiviert:
Code:
{-----------------------Memory Manager Sharing Options------------------------}

{Allow sharing of the memory manager between a main application and DLLs that
 were also compiled with FastMM. This allows you to pass dynamic arrays and
 long strings to DLL functions provided both are compiled to use FastMM.
 Sharing will only work if the library that is supposed to share the memory
 manager was compiled with the "AttemptToUseSharedMM" option set. Note that if
 the main application is single threaded and the DLL is multi-threaded that you
 have to set the IsMultiThread variable in the main application to true or it
 will crash when a thread contention occurs. Note that statically linked DLL
 files are initialized before the main application, so the main application may
 well end up sharing a statically loaded DLL's memory manager and not the other
 way around. }
{$define ShareMM}

  {Allow sharing of the memory manager by a DLL with other DLLs (or the main
   application if this is a statically loaded DLL) that were also compiled with
   FastMM. Set this option with care in dynamically loaded DLLs, because if the
   DLL that is sharing its MM is unloaded and any other DLL is still sharing
   the MM then the application will crash. This setting is only relevant for
   DLL libraries and requires ShareMM to also be set to have any effect.
   Sharing will only work if the library that is supposed to share the memory
   manager was compiled with the "AttemptToUseSharedMM" option set. Note that
   if DLLs are statically linked then they will be initialized before the main
   application and then the DLL will in fact share its MM with the main
   application. This option has no effect unless ShareMM is also set.}
  {$define ShareMMIfLibrary}

{Define this to attempt to share the MM of the main application or other loaded
 DLLs in the same process that were compiled with ShareMM set. When sharing a
 memory manager, memory leaks caused by the sharer will not be freed
 automatically. Take into account that statically linked DLLs are initialized
 before the main application, so set the sharing options accordingly.}
{$define AttemptToUseSharedMM}

{Define this to enable backward compatibility for the memory manager sharing
 mechanism used by Delphi 2006 and 2007, as well as older FastMM versions.}
{$define EnableBackwardCompatibleMMSharing}
Dann kommt zwar immer noch die oben gezeigt Fehlermeldung beim laden der DLL. Die Fehlermeldungen beim beenden sind jedoch weg!
Muss ich noch etwas zusätzliches für Memory Share angeben?

Da ich mich mit FastMM nicht auskenne...wie kann ich das noch zum laufen bringen? Einen anderen Memorymanger benutze (soweit ich weis) nicht! Wo kann man das bei Delphi 2007 nachsehen?

Auch bekomme ich das mit dem FastMM Log-File nicht hin. Wo wird diese gespeichert?
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#8

Re: Dynamische DLL Funktion bringt nur Fehler

  Alt 18. Okt 2008, 21:07
Stell dazu besser eine neue Frage (neuer Thread). Dann melden sich bestimmt auch welche, die sich mit FastMM auskennen. Ich gehöre nicht dazu.
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:08 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz