[Lazarus] Library, Threads and Gui
Kostas Michalopoulos
badsectoracula at gmail.com
Tue Jun 5 16:02:30 CEST 2012
On 5/6/2012 9:29 πμ, Mattias Gaertner wrote:
> The "is" operator requires that the library uses the VMTs of the main
> application.
What does that imply exactly? I made a quick app to test the possibility
of using DLLs for plugins. Both the app and the DLL uses a unit that
contains the following class:
TGBrush = class(TComponent)
protected
function GetBrushEditor: TWinControl; virtual; abstract;
function GetName: string; virtual; abstract;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure Push(ACanvas: TCanvas; X, Y: Integer); virtual;
procedure Release(ACanvas: TCanvas; X, Y: Integer); virtual;
procedure Draw(ACanvas: TCanvas; X1, Y1, X2, Y2: Integer); virtual;
abstract;
property BrushEditor: TWinControl read GetBrushEditor;
property Name: string read GetName;
end;
And also another class that contains a list with TGBrush objects like
the above. These objects access both a TCanvas from the main application
and will return a TWinControl descendant (most likely, but not
necessarily, a TFrame designed in Lazarus) created by the DLL that will
be embedded in a TPanel in the main application.
When adding a new object i use the "is" operator to see if it is a
descendant of TGBrush and this always fails. My current setup is to pass
the memory manager of the application and the shared brushes object to
the library:
var
MemMgr: TMemoryManager
GetMemoryManager(MemMgr);
RegProc:=TGBrushDLLRegisterProc(GetProcedureAddress(Lib,
'BrushDLLRegister'));
if Assigned(RegProc) then RegProc(MemMgr, GBrushes);
And from the DLL side use the memory manager as the first thing and call
Application.Initialize:
procedure BrushDLLRegister(const AppMemoryManager: TMemoryManager;
GBrushes: TGBrushes);
begin
SetMemoryManager(AppMemoryManager);
// The call to Application.Initialize is made because i read
// in the forums that it is needed from libraries to "sync"
// the two instances together
Application.Initialize;
// here the TGBrush constructor checks if its owner is a
// TGBrushes descendant using the "is" operator and fails
TSprayGBrush.Create(GBrushes);
end;
Why exactly the "is" operator fails and how can it be fixed? And how
will all the above work under Windows, Linux and Mac OS X?
If needed i can put somewhere the full program i used for testing, but i
think the above shows what i'm trying to do.
Kostas "Bad Sector" Michalopoulos
More information about the Lazarus
mailing list