Unable to cast object

G

Guest

I have a C++/CLI interface IPlugin in one assembly (a windows service) that
is inherited and implemented in another assembly (dll) by a class CPlugin. I
want to be able to create instance of this class dynamically at runtime, so I
load the dll assembly using

Assembly^ assembly = Assembly::LoadFrom(directory + assemblyName + ".dll");

then create an instance of CPlugin using

Object^ obj = (assembly->CreateInstance(assemblyName+".C"+assemblyName));

Where assemblyName is PlugIn. This creates an instance of an object quite
happily. But when I try to do the following it throws an InvalidCastException

IPlugin^ iPI = safe_cast<IPlugin^>(obj);

I have also tried dynamic_cast which returns a undefined object.

So the question is why can't I cast CPlugin to IPlugin when it inherits it
publically?

Thanks

Colin
 
V

Vladimir Nesterovsky

I have a C++/CLI interface IPlugin in one assembly (a windows service) that
is inherited and implemented in another assembly (dll) by a class CPlugin.
I
want to be able to create instance of this class dynamically at runtime,
so I
load the dll assembly using

Assembly^ assembly = Assembly::LoadFrom(directory + assemblyName +
".dll");

then create an instance of CPlugin using

Object^ obj = (assembly->CreateInstance(assemblyName+".C"+assemblyName));

Where assemblyName is PlugIn. This creates an instance of an object quite
happily. But when I try to do the following it throws an
InvalidCastException

IPlugin^ iPI = safe_cast<IPlugin^>(obj);

I have also tried dynamic_cast which returns a undefined object.

So the question is why can't I cast CPlugin to IPlugin when it inherits it
publically?

Did you declare IPlugin both in service assembly and in plugin assembly?
 
G

Guest

Did you declare IPlugin both in service assembly and in plugin assembly?
No, I declared it in the service and then referenced it in the plugin
assembly.

Colin
 
V

Vladimir Nesterovsky

Did you declare IPlugin both in service assembly and in plugin assembly?
No, I declared it in the service and then referenced it in the plugin
assembly.

Colin

Can you check in the debugger whether there are two instances of the service
assembly are loaded? Once in the BizTalk I've seen that some assembly was
loaded twice from GAC and from a bin folder. In spite of the fact that
assembies was identical runtime considered them as different. As result
classes created in one assembly could not be casted to corresponded classes
from second assembly.
 
G

Guest

There is definitely only one instance of the service and plugin assembly
being loaded, which are the ones I expect from the debug folder, not the GAC.

Thanks for your help so far

Colin
 
G

Guest

I should probably have mentioned that I am running the service as a console
application for debugging purposes, but it will be a service in the end.
 
H

Holger Grund

Colin Desmond said:
There is definitely only one instance of the service and plugin assembly
being loaded, which are the ones I expect from the debug folder, not the
GAC.
To be really certain you can compare the assembly locations.
E.g. IPlugin::typeid->Assembly->Location and
obj->GetType()->GetInterface("IPlugin")->Assembly->Location.
LoadFrom can silently fall back to the Load context.

You might also want to take a look at the metadata tokens
(Type::MetadataToken) to make sure you have the same types
within matching assemblies.

You aren't passing the object to another appdomain before
doing the cast, do you? But I think you would get a useful
text in the Exception message (telling you can't cast a proxy)
to the real type or vice versa.

-hg
 
G

Guest

Thanks Holger, this was very interesting.

The IPlugin is in the service exe assembly where as the obj's IPlugin in is
shown to be in the dll assembly, despite it not being defined there. It is
simply included as a reference and used in the class definition!

I presume because these don't match then .Net thinks they are not the same.

Colin
 
G

Guest

Holger,

When I compare the metadatatokens, I get the same int value for both of
them, does this mean they are the same?

I am not aware of passing the object into another appdomain at any stage,
but I wouldn't know it even if I did so. Certainly the safe_cast error
message is moaning about not bein able to convert types, nothing to do with
proxies.

Thanks

Colin
 
V

Vladimir Nesterovsky

"Colin Desmond" <[email protected]> ÓÏÏÂÝÉÌ/ÓÏÏÂÝÉÌÁ ×
ÎÏ×ÏÓÔÑÈ ÓÌÅÄÕÀÝÅÅ:
Thanks Holger, this was very interesting.

The IPlugin is in the service exe assembly where as the obj's IPlugin in
is
shown to be in the dll assembly, despite it not being defined there. It is
simply included as a reference and used in the class definition!

I presume because these don't match then .Net thinks they are not the
same.

Can you verify with ILDASM that IPlugin is not declared in the dll assembly?
 
G

Guest

Can you verify with ILDASM that IPlugin is not declared in the dll assembly?

Thanks Vladimir, that lead me in the right direction. I have forgotten to
make the interface public in the service assembly so I had had to include the
header file into the dll assembly in order to get it to compile! This meant
it was defined in both assemblies!!!

What an idiot, and thank you to all who helped!

Colin (head hanging in embarrassed shame!)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top