IConnectionPointContainer & C#

C

carl_bevil

Hi all. I'm trying to do something that I think should be fairly
simple. We have some COM objects that used to communicate directly
with each other. I've created a "shim" object in C# that intercepts
all calls from client COM objects and forwards them on to a single
server COM object. The server object, the clients and the shim object
are all in separate processes on the same machine.

The shim object needs to implement all the interfaces the server
object does. I've been able to get all the interfaces working except
IConnectionPointContainer, and it's driving me nuts. I just want to
forward everything, so instead of using delegates I implemented the
raw interface:


public class MyClass: ServicedComponent, /* Other interfaces... */,
IConnectionPointContainer
{
void IConnectionPointContainer.EnumConnectionPoints(out
IEnumConnectionPoints ppEnum)
{
_comServerObject.EnumConnectionPoints(out connectionPoints);
}

void IConnectionPointContainer.FindConnectionPoint(ref Guid riid, out
IConnectionPoint ppCP)
{
_comServerObject.FindConnectionPoint(ref riid, out ppCP);
}
/* Other methods... */
}


This object is a serviced component, creating a COM+ application, but
I'm not sure if that makes any difference.

Anyway, the code seems simple enough, right? Well,
FindConnectionPoint gets called and I can put a breakpoint in the C++
COM code and see that the expected value is getting returned -- we use
the standard IConnectionPointContainerImpl implementation for the
server. And ppCP *seems* to have a valid object in it -- it's not
null at least. But the COM client that gets this IConnectionPoint
object is unable to make calls on it (it generates an access
violation, 0xc0000005).

So I tried putting some test code in the function:

void IConnectionPointContainer.FindConnectionPoint(ref Guid riid, out
IConnectionPoint ppCP)
{
_comServerObject.FindConnectionPoint(ref riid, out ppCP);
Guid guid;
ppCP.GetConnectionInterface(out guid);
}

.... to see if the object was OK in C#. It does not appear to be. I
can again watch what happens in C++ by putting a breakpoint in
GetConnectionInterface. The first thing I notice is that, rather than
calling GetConnectionInterface directly, Advise is called first!
(Advise calls GetConnectionInterface, or I may not have discovered
this). I have no idea why or how Advise is getting called, and its
parameters are corrupt and cause an exception to be thrown back to
C#. I assume that something is getting corrupted between COM and C#,
but I'm not sure what, as I've got plenty of other code that does
similar operations with no problems (nothing with connection points,
though).

So... can anyone give me a hint as to what am I doing wrong here? Is
it possible that things are not getting marshaled properly by the
server's FindConnectionPoint?

Thanks,

Carl
 
N

Nicholas Paldino [.NET/C# MVP]

It's very possible. In this case, you are doing a hell of a lot of
interface proxy marshalling, and I'm not surprized that something is getting
mucked up along the way. If you really want to use a serviced component
(COM+) and use events as well (which is what connection points are), then I
would recommend using Loosely Coupled Events in COM+, and then having your
shim fire the events, and the clients subscribe to that, if possible.
 
C

carl_bevil

Thanks for the response. We want to use COM+ mainly for the role-
based security it provides, but I'm open to other options (although it
may mean re-designing my project.. :). One of the requirements of my
project is to not change the client code -- clients should be
blissfully unaware that they are now talking to this new COM+
component instead of the old COM object (there's a lot of code that
references this object...).

I haven't read up on LC Events; I had thought that they only worked
with COM+ objects. I'll look into it some more to see if it is a
viable solution for me.

Carl
 

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