![]() |
AW: DLL und Threads
Zitat:
|
AW: DLL und Threads
.. nicht in der DLL nur im Thread. Der Thread soll die DLL benutzen.
DLL:
Delphi-Quellcode:
TParser, instanziert im Thread:
procedure ParseDeviceParameters(const aText: PChar; Parameters: TDeviceParameterList)
. . exports ParseDeviceParameters . .
Delphi-Quellcode:
Aus dem Thread:
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;
Delphi-Quellcode:
FParser.ParseDeviceParameters(PChar(FResponseText), FDeviceParameterList);
|
AW: DLL und Threads
Dir ist aber bewusst, dass man von und zu DLLs keine Objekte übergeben kann, sondern höchstens Interfaces?
|
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:
und baue den um, so dass der niemals threadsafe benutzt werden kann:
TSimpleParser
Delphi-Quellcode:
Hast du das in der DLL so ähnlich gelöst, dann kannst du das threadsafe vergessen.
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. |
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. |
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.
|
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 14:09 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