Hallo Leute!
Ich hoffe auch ihr seit gut ins Jahr 2009 gerutscht.
Ich versuche mich hier gerade an der Umsetzung einer
ActiveX Bibliothek die über die von Delphi bekannten Automatisierungsobjekte enthält. Soweit alles ok, funktioniert auch super. Da ich jedoch in der Bibliothek eine Datenbank verwenden will, muss der Einstieg den die Anwendungen über
COM nutzen ein Singleton sein. Also alle bekommen die gleiche Instanz der Anwendung zugeteilt.
Delphi-Quellcode:
unit COM_MyServer;
{$WARN SYMBOL_PLATFORM OFF}
interface
uses
ComObj,
ActiveX, MyServerLib_TLB, StdVcl, Windows;
type
TSingletonAutoObjectFactory =
class(TAutoObjectFactory)
private
FCOMObj : TComObject;
protected
{ Protected-Deklarationen }
function CreateComObject(
const Controller: IUnknown): TComObject;
override;
destructor Destroy;
override;
end;
type
TMyServer =
class(TAutoObject, IMyServer)
private
bIsLoaded : Boolean;
protected
procedure TestServer;
safecall;
function InitDB: Integer;
safecall;
end;
implementation
uses ComServ;
{ TMyServer }
procedure TMyServer.TestServer;
begin
windows.OutputDebugString(PCHAR('
TMyServer.TestServer: erfolgreich ausgeführt'));
end;
function TMyServer.InitDB: Integer;
begin
if (bIsLoaded = true)
then
begin
windows.OutputDebugString(PCHAR('
TMyServer.InitDB: DB allready loaded'));
end
else
begin
bIsLoaded:=true;
end;
end;
{ TSingeltonAutoObjectFactory }
function TSingletonAutoObjectFactory.CreateComObject(
const Controller: IInterface): TComObject;
begin
if FCOMObj =
nil then
FCOMObj :=
inherited CreateComObject(Controller);
result := FCOMObj;
end;
destructor TSingletonAutoObjectFactory.Destroy;
begin
FCOMObj :=
nil;
inherited;
end;
initialization
// TAutoObjectFactory.Create(ComServer, TMyServer, Class_MyServer,
// ciMultiInstance, tmApartment);
TSingletonAutoObjectFactory.Create(ComServer, TMyServer, Class_MyServer,
ciMultiInstance, tmApartment);
end.
Der zugehörige Client sieht ganz einfach aus. Dieser importiert die TLB und greift dann auf den Server zu.
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
MyServer:=CoMyServer.Create;
MyServer.TestServer();
MyServer.InitDB();
end;
Nun ist mein Problem, dass diese Singleton-Umsetzung nicht ganz funktioniert. Wenn ich in in EINER Anwendung den ButtonClick mehrfach ausführe, dann erhalte ich im
COM-Server auch die Meldung, dass die
DB bereits initialisiert wurde. Klappt also wunerbar, ist ein Singleton.
Wenn ich jedoch diese Clientanwendung parallel ein zweites (drittes...) Mal starte und die Aktion ausführe, dann verhalten sich diese genauso wie die erste. Beim ersten Klick wird die
DB initialisiert und dann nicht mehr.
Was ich nun gern hätte ist ein übergreifendes Singleton. Egal wie viele Programme darauf zugreifen, alle bekommen die gleiche Instanz. Momentan scheint das Singleton nur an die aufrufende Programminstanz gebunden zu sein.
Hat jemand da eine (oder mehrere) Ideen? Schon mal Danke im Voraus!