문제

I am using COM Interop. I have a call in VB6 which returns a string of roughly 13000 chars. If I execute the call in pure VB6 it takes about 800ms to execute. If I execute it via c# and COM Interop it takes about 8 seconds. I'm assuming the delay is caused by marshaling.

If I am correct about marshaling, I'd be grateful if someone could suggest the fastest way I can get this into C#. e.g. Would it be better to a) expose it as a byte array b) provide a byref string param into the VB6 layer

I would appreciate some sample code as well. I tried the

Marshal.PtrToStringAuto(Marshal.ReadIntPtr(myCOMObject.GetString, 0)

to no avail.

--

Following on from Franci's comment. I am simply referencing the VB6 dll (so in process) from a C# dll. Here's an extract from OLEView

interface _MyCOMObect : IDispatch {
        ...
        [id(0x60030006)]
        HRESULT GetString(
                        [in] _IEventHistory* p_oEventHistory, 
                        [out, retval] _IXML** );
        ...
    };

    [
      uuid(09A06762-5322-4DC1-90DD-321D4EFC9C3E),
      version(1.0),
        custom({17093CC6-9BD2-11CF-AA4F-304BF89C0001}, "0")
    ]
    coclass MyCOMObject {
        [default] interface _CFactory;
    };

    [
      odl,
      uuid(C6E7413F-C63A-43E4-8B67-6AEAD132F5E5),
      version(1.0),
      hidden,
      dual,
      nonextensible,
      oleautomation
    ]

I should probably point out that the parameter (p_oEventHistory) is another COM object which I am instantiating in C# but that takes about 80ms

S

도움이 되었습니까?

해결책

A couple of things: -

  1. My VB6 is a little rusty, but your IDL excerpt suggests the GetString method actually returns an object that implements the IXML interface. I'm kind of surprised that Marshal.PtrToStringAuto can do anything useful with this. Could you change the VB6 so that it actually returns something of type String?

  2. The effect of COM+ is potentially enormous. Firstly I would suggest that you compare timings for the first invocation versus subsequent invocations. COM+ will need to spin up a host process for your VB6 component the first time it's invoked so the first call is always more painful. Note this happens on first invocation, not on object instantiation. Secondly, the way your component is configured in COM+ can make a big difference too; if you disable all the COM+ services that you don't actually need (e.g. transactions) you might be able to remove some of the interception logic that COM+ places around all method invocations. Ultimately, if you don't need the services that COM+ provides, don't use it.

다른 팁

I would consider using memory mapped files or named pipes.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top