tags:

views:

39

answers:

0

We have what we think is a marshaling problem with a renderer object when called across process boundaries. The renderer is an ATL COM server with a COM object that implements the IPoints interface defined below:

typedef [uuid(B0E01719-005A-427c-B9DD-B42A18E969AE)] struct Point
{
   double   X;
   double   Y;
} Point;

[
  object,
  uuid(3BFECFE3-B4FB-4f14-8257-6E065D02E3B3),
  helpstring("IPoints Interface"),
  dual,
]

interface IPoints : IDispatch
{

  HRESULT DrawPolyLine([in] long hDC, 
                   [in] short count,
                   [in, size_is(count)] Point * points
                  );

// many more like DrawLine

}

The count parameter represents the number of points and the points parameter represents an array of the actual points. We have two process running, a graphical display process (GDP) and a tabular (grid) display process (TDP). A factory in the GDP, written in C#, creates the renderer and the clients of the renderer in the GDP. When the clients call into the renderer, everything displays correctly. The renderer is created at start up BTW.

There is another factory in the TDP, written in VB6, that calls into the factory in the GDP to create the clients. When the clients call into the renderer, only the first point in the array is marshaled correctly, all the other points are garbage. Seems that the rendering works only when the client creation is started from the same process as the renderer.

Now, i am not sure what the solution to this problem is. It seems that if we can guarantee that the clients are always created from a thread in the same GDP process as the renderer then the points are marshaled correctly. We tried using a background thread from the Thread Pool in C# and it indeed worked.

The problem is that Windows Forms created from the clients stopped working because accessing the form's controls from a thread other than the thread that created the control is not allowed. We might change the calls to access the forms but we have quite a few of them and are trying to look into a different solution that might involve making changes to the renderer. The other problem is that the renderer is legacy code and we can't just change the interface. I am wondering what can we do to the renderer's interface that would help with marshaling from across process calls. Any ideas would be greatly appreciated.