.NET Remoting (Passing COM+ RCW Possible?)

Posted on 2006-04-14
Last Modified: 2008-02-07
I've just about given up - I think I'm going to have to scratch my current data flow architecture for my up-coming project and start over.  Here's what I'm generally getting :

          "InvalidCastException: Return argument has an invalid type"

And I'm not sure if I'll be able to get past it.  Some of the objects that I need to pass are objects in an interop assembly (a vendor's API) that's generated from VB6 --> tlbimp --> .net DLL rcw (runtime callable wrapper).  Here's the problem - I can't set any of those objects to serializable, because I can't change the code, so what can I do?  I've thought about making managed wrappers for all of the objects and I still might ... here's what I *WANT* to do:

[APPLICATION] ---> (calls your own registered assemblies via OLE Automation) ---> [MyOLEHook : IWhateverInterfaceIsRequiredForTheHook]

Now, I have a number of these OLE Hooks and I don't want any of me 'real' code here - i want to use these as proxies.  Currently, this is what happens:

[MyOLEHook.SomeTriggeredMethod(string str1, OleObject obj1)]
    RemotingClientClass client = new RemotingClientClass();
    IWhateverInterfaceIsRequiredForTheHook realHook = (IWhateverInterfaceIsRequiredForTheHook) client.GetRealHookFromServer("IWhateverInterfaceIsRequiredForTheHook");


what I have set up now works GREAT for passing along any .NET managed & serializable object that both the client and server assemblies have references to, but I haven't been successful in passing COM objects.  is it possible at all?  or will i have to do this, instead : (?)

[MyOLEHook.SomeTriggeredMethod(string str1, OleObject obj1)]
    RemotingClientClass client = new RemotingClientClass();
    IWhateverInterfaceIsRequiredForTheHook realHook = (IWhateverInterfaceIsRequiredForTheHook) client.GetRealHookFromServer("IWhateverInterfaceIsRequiredForTheHook");
    OleObject1Managed mgd1 = new OleObject1Managed(obj1);



now, for those of you who're asking WHY i don't just implement the code in the hook that the application calls ... here's why.

1) the assemblies that act as hooks for the application need to be registered and they need to have certain names and ... they're just not fun to work with.
2) plugin-architecture.  the way that I have things set up now (if the COM objects would pass along Remoting) ... I have a customized application which loads ... finds all of the implementations for these various hooks (there could be many for each hook) ... you can select your 'Active' implementation of any one of the hooks and change them at any time, effective immediately ... and the hooks can be named whatever I want, so long as they implement certain interfaces.  I don't like vendors' APIs denormalizing my code - I'd rather set something up on the vendor application side that I can talk to however I want to and in a managed environment.

So -- does anyone know of any tricks I can use to be able to pass objects from a library created with tlbimp along Remoting channels?  *OR* do you recommend a good way of wrapping them?  Should they be wrapped like ...

1? : class OleObject1Managed : OleObject1Class

2? : class OleObject1Managed : OleObject1 (this is an interface - this is what tlbimp does when you run it against an assembly ... it makes ClassName interfaces and ClassNameClass classes)

3? : class OleObject1Managed
           protected OleObject1 _innerOleObject1;
           public OleObject1 InnerOleObject1
               // getters setters

4? : class OleObject1Managed
           public OleObject1Managed(OleObject1 oleObject)
               // set properties of managed class based on OleObject1 ... but this doesn't allow for methods, etc, which isn't acceptable.  We need to be able to ue the object's methods.


I could really use some advice on this one!  Given the amount of development time spent on this ... I'll probably make wrappers of some kind if I can make them work.

What do you guys think?  TIA
Question by:eventprostrategies
    LVL 9

    Author Comment

    Source Code (wo. NAnt) : (156 KB)
    Source Code (w. NAnt) : (4.52 MB)

    I found the following bit** that made me think that dealing with RCWs in Remoting shouldn't be a big deal.  Now, the source I'm showing isn't my real source (corporate - no can do), and it isn't throwing the Invalid Type error but it is having some issues and i built it JUST for EE so you can have a look at the architecture and see if you can make it work.  The problem I'm having with this one is, when I try to pass a Dog to the real hook, nothing happens ... the client just times out and I don't get an exception or anything (not that I could catch).

    So here's a description of the source for anyone who takes the time to check it out:

    [[ "Remoting Rover" ]]

    [[ Concept ]]
    Vendor application (Veterinary app called 'VetApp' which is a database of animals) has OLE Hooks, including one called DogsHook (seen here) which is triggered when there's a DogInsert/DogEdit/DogDelete and, just for good measure, when there's a Bark.  We can't to consume these events with an assembly and pass all of the hook methods and the parameters passed on to another implementation via .NET Remoting.

    All assemblies are pre-compiled in the bin directory of the project folder.  If you want to make changes and re-compile (if you don't have NAnt on your machine, you can download the source with NAnt and, no installation required, the builds should all work), make your changes and run 'rebuild.bat' in the src folder.

    [[ Assemblies ]]
    -  RCW of an unmanaged assembly (that simply contains a Very simple 'Dog' class - this is our 'unmanaged' and wrapped object that we want to pass around)

    -  This assembly has all of the interfaces for VetApp hooks in it, in this case just IDogsHook.  These are used for compile-time errors if the implementing classes don't implement VetApp hooks correctly, and also as objects that can be passed around via Remoting.

        - Hook (represents a hook)
        - ProxyHook (represents a hook that connects to the ProxyClient to pass data along to the server)
        - ProxyServer (remotable object, stores references to Proxy hooks and 'Real' hooks)
        - ProxyServerManager (used to start and host a ProxyServer)

    -  This is the hook that we want VetApp to pass things to, and we want ProxyHook to, in turn, pass all of this data further along, across app boundaries to our Remoting server

    -  This is a 'real' implementation of our hook.  it's registered with the server and, when the server gets a request from a ProxyHook for it's real implementation, it gives a reference to the RealHook.  really, the server-hosting application loads a directory of these and the end user can select which one is active.

    -  Console app being used to emulate VetApp.  run it after you start the server (below)

    -  Console app being used to host the server and register our 1 real hook with it.


    ... that makes me think that I shouldn't have a problem with this.

    "It is possible to call COM components directly through COM Interop Services. When the .NET Remoting client object creates an instance of a COM object, a runtime callable wrapper (RCW) exposes the unmanaged object and acts as a proxy for it. To the .NET client, this wrapper appears to be just like any other managed class. The wrapper simply marshals calls between managed (.NET) and unmanaged (COM) code."

    Accepted Solution

    Because you have presented a solution to your own problem which may be helpful to future searches, this question is now PAQed and your points have been refunded.


    Featured Post

    Training Course: Java/J2EE and SOA

    This course will cover both core and advanced Java concepts like Database connectivity, Threads, Exception Handling, Collections, JSP, Servlets, XMLHandling, and more. You'll also learn various Java frameworks like Hibernate and Spring.

    Join & Write a Comment

    In one of my recent projects, I was working with IP cameras, I need to take some pictures from the camera and do some processing on it. The first step, was to retrieve the image from camera into Image object. So that it can be displayed or …
    Introduction Although it is an old technology, serial ports are still being used by many hardware manufacturers. If you develop applications in C#, Microsoft .NET framework has SerialPort class to communicate with the serial ports.  I needed to…
    Hi everyone! This is Experts Exchange customer support.  This quick video will show you how to change your primary email address.  If you have any questions, then please Write a Comment below!
    Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…

    730 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    16 Experts available now in Live!

    Get 1:1 Help Now