COM Cast issue when retrieving a custom Plug In From Rhino

Dear McNeel Team,

I am trying to interact with a custom made Rhino Plug In through a COM Interface. Basically, as explained by dale here, Rhino is started from an Activator object, then the custom made plug in is instanciated and we retrieve an object from an overrriden function “GetPlugInObject”. The PlugIn Client is a WCF Service.

But, when I try to cast the COM Object to its native type (in order to use its exposed methods), I get a Microsoft.CSharp.RunTimeBinder.RuntimeBinderException : Cannot cast System._COMObjet [to the native type]. Trying to use the plug in object as a dynamic variable doesn’t work neither, I face an implicit conversion error.

Would you have any hint about this issue? I am unfortunately struggling for many days now. I have been told that this problem can appear if there is a mix between 32 and 64 bits programs and references. But, both projects (the WCF service and the Rhino Plug In are compiled using “Any CPU” config and are referencing the same RhinoCommon 64 bits DLL.

Any help would be highly appreciated, I am quite far from my comfort zone with this issue!

  • Xavier

Hi @Xavier_Ayme,

Does this sample provide any help?

– Dale

Hi @Xavier_Ayme,

Can you try to first create a wrapper around your COM object with CreateWrapperOfType, before calling any methods on it?

Thanks to both of you for your answer,

Unfortunately none of these solution works, I get the same problem with the plug in from @dale.

The wrapper sounded like a great idea but I got a different exception : System.ArgumentException, type should be _ComObject. I called it like this :
RhCOM comObject = System.Runtime.InteropServices.Marshal.CreateWrapperOfType(plugIn, typeof(RhCOM));
RhCOm being the object I retrieve from the GetPlugInObject method.

So, two questions came to my mind :

  1. Should the solution be registered as a COM Interface to be able to call the methods from the object? I cannot build the solution when I tick the box, it says that Rhinocommon.dll cannot be registered, but I am maybe missing a step somewhere.
  2. Following @djordje solution, would you have any advice on how to implement a COM object from scratch? It looks horribly complicated but may be the solution to create the wrapper.

Thanks for your help, I am completely stuck with this issue.

  • Xavier

Hi Xavier,

I am wondering if there is a difference in a way in which CreateWrapperOfType should be called, between ironpython and C#. In ironpython, I assume it will be called as:

plugin_object = System.Runtime.InteropServices.Marshal.CreateWrapperOfType(COM_obj, Rhino.PlugIns.PlugIn)

Hi @Xavier_Ayme,

To be of further assistance, we may need the code to a sample project that you cannot make work.

– Dale

Hello @dale, we’re still trying to narrow down the issue and I will likely come back to you shortly. We may have found something today.

Thanks for your commitment

Hello @dale, I think we found the root cause of this issue (but we are not 100% sure, we may have solved it by luck).

For the cast to work (or internal cast if you call directly a method on the COM object) , the plug in project needs to be registered for COM Interop in Visual Studio Properties Panel, as per screenshot below.

Problem is : registering for COM requires that a local copy of Rhinocommon.dll is copied into the bin folder at compilation time. I actually have no idea why. Should you do this, you create a conflict since Rhino Plug In file SHOULD NOT have a copy of Rhinocommon.dll in the same folder, so Rhino starts but instantly detects a problem.

So, what we did and looks like being working is : registering the Plug In for COM, set copy local for the Reference Rhinocommon.dll and create a Post Build Event which deletes it with the command : del “$(TargetDir)rhinocommon.dll”

Does all of this make sense to you? Do you think that compiling against a local copy of Rhinocommon and deleting it will create a lot of trouble that we don’t even think of?

Thanks !

Hi @Xavier_Ayme,

In general, you don’t want to check the Register for COM interop option in a Rhino plug-in project because the COM object in the plug-in cannot be created without Rhino. Thus there is no reason for all of the COM registration (in the Windows Registry).

It is not necessary to cast the COM object, returned by Rhino, to your class type in order to call functions on it, as demonstrated with sample I posted earlier.

In situations where you want to cast an unknown object as a known object, then it is common to import a type library that defines the known object. Generating type libraries on the .NET side is something that I am not familiar with.

As far as what you’ve done to make your project work, I really don’t have any comments other than what I’ve made. To be of further assistance, I will need more background on what you are trying to do and why. And I’ll need some sample source code, of course.

– Dale

Hi @dale,

Ok understood, appreciate your well explained feedback.

So there will still be an unknown why the method call on the COM Object (as per your code sample) failed at first and now works… Should we have any explanation in the future I will update this post.

Thanks for your time!

– Xavier