Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi DLL und Threads (https://www.delphipraxis.net/180042-dll-und-threads.html)

DeddyH 18. Apr 2014 13:03

AW: DLL und Threads
 
Zitat:

Delphi-Quellcode:
FParser.ParseDeviceParameters(PChar(FResponseText), FDeviceParameterList);

Wird der Code aus der Anwendung heraus ausgeführt oder nur innerhalb der DLL?

haentschman 18. Apr 2014 13:12

AW: DLL und Threads
 
.. nicht in der DLL nur im Thread. Der Thread soll die DLL benutzen.

DLL:
Delphi-Quellcode:
procedure ParseDeviceParameters(const aText: PChar; Parameters: TDeviceParameterList)
.
.
exports
  ParseDeviceParameters
.
.
TParser, instanziert im Thread:
Delphi-Quellcode:
FDLL: string;
FMasterDeviceDLLHandle: THandle;
procedure LoadDLL;
.
.
constructor TParser.Create(aDLL: string);
begin
  inherited Create;
  FMasterDeviceDLLHandle:= 0;
  FDLL:= aDLL;
  LoadDLL;
end;

procedure TParser.LoadDLL;
begin
  FMasterDeviceDllHandle:= LoadLibrary(PChar(FDLL));
  if FMasterDeviceDllHandle <> 0 then begin
    FParseDeviceParameters:= GetProcAddress(FMasterDeviceDllHandle, 'ParseDeviceParameters');
.
.
  end
  else
  begin
    raise Exception.Create('DLL ' + QuotedStr(FDLL) + ' konnte nicht geladen werden.');
  end;
end;

procedure TParser.ParseDeviceParameters(aText: PChar; ParameterList: TDeviceParameterList);
begin
  FParseDeviceParameters(aText, ParameterList);
end;
Aus dem Thread:
Delphi-Quellcode:
FParser.ParseDeviceParameters(PChar(FResponseText), FDeviceParameterList);

DeddyH 18. Apr 2014 13:14

AW: DLL und Threads
 
Dir ist aber bewusst, dass man von und zu DLLs keine Objekte übergeben kann, sondern höchstens Interfaces?

Sir Rufo 18. Apr 2014 13:15

AW: DLL und Threads
 
Das "Warum DLL" spielt hier doch keine Rolle (persönlich würde ich das auch mit DLL's/Plugins machen).

Es kommt nur darauf an, wie du das in der DLL umgesetzt hast.

Als Beispiel nehme ich mal
Delphi-Quellcode:
TSimpleParser
und baue den um, so dass der niemals threadsafe benutzt werden kann:
Delphi-Quellcode:
unit SimpleParser;

interface

uses
  Classes,
  Parser;

type
  TParserState = procedure( AChar : Char ) of object;

  TSimpleParser = class( TInterfacedObject, IParser )
  private
    FBuffer : string;
    FTokens : TStrings;
    procedure StartState( AChar : Char );
    procedure TokenState( AChar : Char );
  public
    constructor Create;
    destructor Destroy; override;

    function Parse( const AString : string ) : TArray<string>;
  end;

implementation

// unit-globale Variable und ich kann threadsafe vergessen
var
  FState : TParserState;

{ TSimpleParser }

constructor TSimpleParser.Create;
begin
  inherited;
  FTokens := TStringList.Create;
end;

destructor TSimpleParser.Destroy;
begin
  FTokens.Free;
  inherited;
end;

function TSimpleParser.Parse( const AString : string ) : TArray<string>;
var
  LIdx : Integer;
begin
  FTokens.Clear;
  FState := StartState;
  for LIdx := 1 to Length( AString ) do
  begin
    FState( AString[LIdx] );
  end;
  Result := FTokens.ToStringArray;
end;

procedure TSimpleParser.StartState( AChar : Char );
begin
  case AChar of
    ' ' :
      ;
    ',' :
      ;
  else
    FState := TokenState;
    FState(AChar);
  end;
end;

procedure TSimpleParser.TokenState( AChar : Char );
begin
  case AChar of
    ',' :
      begin
        FTokens.Add( FBuffer );
        FBuffer := '';
        FState := StartState;
      end;
  else
    FBuffer := FBuffer + AChar;
  end;
end;

end.
Hast du das in der DLL so ähnlich gelöst, dann kannst du das threadsafe vergessen.

haentschman 18. Apr 2014 13:16

AW: DLL und Threads
 
Ja, solange die DLL den gleichen Lebenszyklus wie die hier verwendeten Generischen Listen geht das. Die Objekte werden in der DLL erzeugt und sind im Adressraum der DLL.

Und wenn ich mir von der DLL in jedem Thread ein Interface geben lasse? Dann sollte es doch wurscht sein ob das DLL Handle überall gleich ist.

himitsu 18. Apr 2014 14:01

AW: DLL und Threads
 
Die Referenzzählung von Interfaces ist (meistens) Threadsicher, aber der Zugriff auf Methoden ist natprlich nicht vor gleichzeitigen Zugriffen geschützt.

haentschman 19. Apr 2014 07:52

AW: DLL und Threads
 
Moin...

Ich habe dann mal die DLL auf Herausgabe eines Interfaces umgestellt. Ich bekomme immer noch die Zugriffsverletzung beim 14. Durchlauf (siehe oben). :roll: Also Alles beim Alten... :thumb:

Dabei ist mir folgendes aufgefallen. Wenn ich die DLL Innerhalb eines Thread lade wird dann der DLL Code trotzdem im MainThread ausgeführt? Obwohl der Thread gut funktioniert, beim Parsen hängt meine GUI... :shock:

Ich bin verwirrt... :)


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:08 Uhr.
Seite 2 von 2     12   

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