COM server instancing

Consider an application X that uses interfaces iA and iB.
iA and iB are implemented by txA and txB, which are tAutoObject descendants.
Suppose iB stores some configuration information, and iA implements some functionality that needs the config info from iB.

A problem arises when iA's client (X) wants to touch the config-info aswell, since both X and iA need *the same* reference to iB. (I think!)

In the unit that implements txA, i have the following line:
  tAutoObjectFactory.Create(ComServer, txA, Class_A, ciSingleInstance);

However, after digging into the VCL sourcecode, it seems that the ciSingleInstance parameter is never used again. It is only stored in the classfactory as a private variable.

Given the above scenario, i do NOT get the same references to iB in iA and X.

I've thought of creating a dll-global variable that gets set in txB.initialize if it is nil.. But how do I tell the second instance of iB to abort it's own initialization and use the dll-global variable instead?

And even then, it does not solve my original problem (X and iA using iB) when X and iA are in different address spaces. That is not a practical situation yet, but I can see it becoming one :(

Got any help?
LVL 1
lowlevelAsked:
Who is Participating?
 
AndersWPCommented:
I think I have a solution to your problem: To get a handle to an already running instance of an automation server, use the GetActiveObject function.

The following code snippet should give you an example:

Var
  Server: Variant;

Server:=Nil;

Try
  Server:=GetActiveOLEObject(<Your server name>);
Except
End;

Try
  If VarType(Server)<>varDispatch Then
    Server:=CreateOLEObject(<Your Server Name>);
Except
  ShowMessage('Could not create server');
End;

In this example, <Your Server Name> should be replaced with the name of your automation server. After executing this code, the variant variable Server will contain a reference to the server.
The code will first try to establish a reference to an existing instance of the server. If this fails (because no instance is running), a new instance is created.

I hope this will help you.

Greetings,
AndersWP

0
 
_art_Commented:
Have you tried ciMultiInstance???? That is it I believe, at least thats what help says.
0
 
lowlevelAuthor Commented:
Nope, it ain't.
0
Cloud Class® Course: Python 3 Fundamentals

This course will teach participants about installing and configuring Python, syntax, importing, statements, types, strings, booleans, files, lists, tuples, comprehensions, functions, and classes.

 
lowlevelAuthor Commented:
Works like a dream :)

Would you also happen to know why i cannot do something like
var dispatch : variant;
    een      : iEen;
begin
  try
    dispatch:=getActiveOLEObject (serverName);
  except
  end;

  if varType(dispatch)<>varDispatch
    then een:=coEen.create
    else een:=iEen(getActiveOLEObject (serverName));
end;

this will compile, it'll even run, but the iEen pointer is invalid and thus causes access violations.
I'd like to be able to convert it to a specific interface type because I like the type-checking that delphi does pre-compiling.
0
 
AndersWPCommented:
You cannot typecast a Variant referencing an automation server directly to an interface type.

To work with interfaces rather than variants, you can do something like the following:

  Try
    een:=GetActiveOleObject(<Your Server Name>) As IEen;
  Except
    On e:EOleError Do
      een:=CoEen.Create;
  End;

The trick here is that the As operator will do the appropriate conversion to your interface type.

I hope this is what you ment.

Regards,
AndersWP
0
 
lowlevelAuthor Commented:
yup, thanx :)

0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.