2010-03-30 13 views
7

Ich verwende COM Interop. Ich habe einen Aufruf in VB6, der eine Zeichenfolge von ungefähr 13000 Zeichen zurückgibt. Wenn ich den Aufruf in reinem VB6 ausführe, dauert es etwa 800ms, um ausgeführt zu werden. Wenn ich es über C# und COM Interop ausführe dauert es ca. 8 Sekunden. Ich nehme an, dass die Verzögerung durch Marshalling verursacht wird.Schnellste Möglichkeit zum Zugriff auf VB6 String in C#

Wenn ich über Marshalling richtig bin, wäre ich dankbar, wenn jemand den schnellsten Weg vorschlagen könnte, den ich in C# bekommen kann. z.B. Wäre es besser, a) als ein Byte-Array zu belichten b) einen brefef String-Parameter in die VB6-Ebene

bereitstellen würde ich auch einige Beispielcode schätzen. Ich habe versucht, die

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

vergeblich.

-

von Franci Kommentar Im Anschluss an. Ich referenziere einfach die VB6 DLL (so in Prozess) von einer C# DLL. Hier ist ein Auszug aus 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 
    ] 

ich wahrscheinlich darauf hinweisen, dass der Parameter (p_oEventHistory) ist ein weiteres COM-Objekt, das ich instanziieren bin in C#, aber das dauert etwa 80 ms

S

+0

Es kann hilfreich sein, wenn Sie einige Details zu Ihrem VB6 und C# -Code angeben. Ist die VB6-Komponente ein Out-of-Process-Server oder Inproc? Was ist das tatsächliche TLB-Fragment für das Objekt und die Eigenschaft, auf die Sie zugreifen? Geht der Anruf über IDispatch oder eine normale COM-Schnittstelle? Verwenden Sie einen Standard-OLE-Marshaller oder einen benutzerdefinierten Proxy/Stub oder sogar einen benutzerdefinierten Marshaller? –

+0

So habe ich es geschafft, 1 Sek von der Zeit zu rasieren, indem ich kein COM-Objekt in den COM-Aufruf injizierte (über den Parameter), sondern alles auf der COM-Seite tat. ABER 7 Sekunden scheint immer noch übertrieben für die Übertragung von 13000 Zeichen! –

+1

Da ist noch etwas anderes los. Das Marshalling eines BSTR dauert Mikrosekunden, nicht Sekunden. Sie sollten den VB6-Code debuggen, legen Sie die C# exe als das Startprogramm fest. –

Antwort

2

Ein paar Dinge: -

  1. Mein VB6 ist ein wenig rostig, aber Ihr IDL Auszug schlägt die GetString Methode tatsächlich ein Objekt zurückgibt, das den IXML-Schnittstelle implementiert. Ich bin irgendwie überrascht, dass Marshal.PtrToStringAuto damit alles machen kann. Könnten Sie die VB6 so ändern, dass sie tatsächlich etwas vom Typ String zurückgibt?

  2. Die Wirkung von COM + ist potenziell enorm. Zuerst würde ich vorschlagen, dass Sie Timings für den ersten Aufruf gegen nachfolgende Aufrufe vergleichen. COM + muss einen Host-Prozess für Ihre VB6-Komponente beim ersten Aufruf aktivieren, damit der erste Aufruf immer schmerzhafter wird. Beachten Sie, dass dies beim ersten Aufruf und nicht bei der Objektinstanziierung geschieht. Zweitens kann die Art und Weise, wie Ihre Komponente in COM + konfiguriert wird, ebenfalls einen großen Unterschied machen. Wenn Sie alle COM + -Dienste deaktivieren, die Sie nicht wirklich benötigen (z. B. Transaktionen), können Sie möglicherweise einige der Abhörlogik entfernen, die COM + allen Methodenaufrufen zuordnet. Wenn Sie die von COM + bereitgestellten Dienste nicht benötigen, verwenden Sie sie nicht.