Link to home
Start Free TrialLog in
Avatar of cabela
cabela

asked on

"as" operator across DLLs

It looks like the "is" and "as" operators do not work across DLLs.

I have an object created in one DLL. For example TStrings.

I pass this object via exported function or a COM interface method to another DLL.

function GetTheObject() : TObject;   external;           (or TStrings actually - it doesn't matter)

myobject = GetTheObject()

When I use the "is" operator on the object like this

  b := myobject is TStrings;

I receive FALSE because the "is" operator is implemented by a TObject.InheritsFrom which goes through virtual tables and each DLL has its own set of vtables that are different.

The situation is even worse with the "as" operator. When I use this I get a "Invalid typecast" exception.

  ts := myobject as TStrings;

Is there any solution to this? How to make the operators work across DLLs?


Avatar of DrDelphi
DrDelphi

IS and AS will work across DLL's with this provision:

 Both the DLL and the Calling routine have to know what the object being called is. For example, if you want to export a Tpicture from your DLL to a VB application, you would need to use IpictureDisp, since VB doesn't know what the hell a Tpicture is. By the same token if you wanted to pass a VBpicture to your DLL , you would need to use something that Delphi understands.

 Now, COM on the other hand has a very small and select group of things that it will pass. Primarialy you would never pass an object, but rather a POINTER to the object. It is possible to pass objects as Variants (or so I have read), but I have never tried it.





Avatar of cabela

ASKER

Well, the problem is not in the getting the pointer but in using it. I do know pretty well what the object is, but I get the Invalid typecast exception when using the as operator. The problem is in the vtables. If I would use the standard cast, it would work ok. But I have no way of checking the actual object type in the other DLL.
Avatar of simonet
It looks like type libraries and ActiveX (read COM) is the way to go.

Alex
I think it should be possible to check the class name e.g. like this:

if myobject.ClassName = 'TStrings' then
  with TStrings(myobject) do
    ...

But I didn't test that...   :-)

Regards, Madshi.
ASKER CERTIFIED SOLUTION
Avatar of aldyn
aldyn

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of cabela

ASKER

Well, there are some problems with both the approaches. The first solves the "as" operator and helps in no way with the "is".

And I am afraid, that I can come across to this problem in some internal part of VCL code when I create a native VCL object in one DLL and call some standard method from another DLL with this object as a parametr. Or do standard packages solve this?

And I cannot use packages because I use COM objects in the DLLs, or can the package work as a ActiveX server?
Why does my suggestion not help with "is"?

  if myobject is TStrings then

  if myobject.ClassName = 'TStrings' then

!!!

Well, but I see problems, if the DLL is written with a different Delphi version than the application is.
Avatar of cabela

ASKER

Well the versions will be the same. But the "is" operator is TRUE when the object is of the exact class type or of a type DERIVED from the class, which is not the case when comparing names.
That's right...   :-(