same class used in two separate libraries not compatible?
Came by a curious case today, that got me thinking about how the object model in delphi really works.
The case:
We have imported a SOAP service that expose a couple of methods, taking objects as parameters. Delphi generates classes/interfaces that we use to communicate with the soap service, and the objects used as parameters all inherit from TRemotable.
For different reasons, we have put all the communication with the soap service into a dll.
We then tried to instantiate the objects that should be sent in the main executable, and pass it over to the libr开发者_开发问答ary for serialization and sending.
Now, that did not work, but gave an exception that I did not expect.
It said that the object we where trying to send to the soap service, must inherit from TRemotable, but it does. By inspecting the object, we can see that the class is the imported class from the wsdl, and that the parent class is indeed TRemotable.
Building with packages solves this issue.
The question:
Is it so that a class defined in a source file, shared between two libraries, ends up as different classes at runtime? If so, why is that?
As far as I know, it should be ok to pass objects between libraries. How, then, is strong typing ensured, and to what extent will object instances be compatible to each other?
Yes, the same class in different DLLs are different. The classes in each DLL will be loaded at runtime and point to different memory, so A.ClassType = B.ClassType
will fail, even for the same source files. You can still pass the objects around and they'll work correctly, except in cases like this where it's using "is" or "as" to compare the classes themselves. Strong typing is only ensured in that the compiler assumes the classes match when you compile the DLL and main application. There's no protection against loading a DLL with one version of an object and a newer application trying to use an modified object declaration. If you want that you'll need to use packages.
You can try passing the parameter as a TObject, and on either end, cast as your TRemotable. I haven't tried this particular case, but I know I've passed TObject into a DLL like that. I also have a similar DLL for SOAP, and in my case this wouldn't work as my SOAP DLL is compiled with D2007 SOAP libraries and for complicated/legacy reasons, the rest of the app is D2005.
精彩评论