2009-03-27 13 views
1

ich ein ATL COM-Server haben, wobei das Verfahren für die SchnittstelleKann nicht bekommen SAFEARRAY mit Interop arbeiten

STDMETHODIMP CWrapper::RUN(long iDataSize, SAFEARRAY** iData) 

und die MIDL für diese Funktion ist sieht aus wie

[id(1), helpstring("method RUN")] HRESULT RUN([in] long nSize, [in, size_is(nSize)] SAFEARRAY(_MyDataType*)* iData); 

ich importieren die tlb von diesem Projekt mit tlbimp, also kann ich native Arrays verwenden. Ich rufe es dann von C#

m_ServerWrapper.RUN(iInputs.Length,ref iInputs) 

wo Eingänge ist bereits zugewiesen und gefüllt mit einem anderen COM-Objekt aus meinem C# -Programm. Jetzt, wenn ich den C++ - Wrapper anrufe, habe ich eine BadPtr für mein safearray und der Aufruf in ein nachfolgendes COM-Objekt von CWrapper::RUN schlägt fehl, wobei das Array nicht zur finalen DLL kommt. Es erscheint als nicht zugewiesen. Hat jemand eine Ahnung, was ich falsch mache? Danke

EDIT: Ich hätte sagen sollen, dass das Array in C# gut aussieht.

EDIT2: Der Debugger zeigt iData safearray von IDispatch* = 0x0000000 <Bad Ptr>, 5, 0x0000000 <Bad Ptr>({lpvtbl = 0xblahblah},.... So scheint es, dass einige meiner Informationen dort ankommen.

+0

Ist _MyDataType auch in der IDL definiert? Wenn nicht, sollten Sie es dort tun. Eine andere Sache: Warum brauchst du nSize? SAFEARRAY behält seine eigene Größe bei. –

Antwort

0

Ein normales C# -Array ist nicht dasselbe wie ein SAFEARRAY. Ich glaube, Sie haben Ihren eigenen machen:

[StructLayout(LayoutKind.Sequential)] 
struct SafeArray 
{ 
    public ushort dimensions; 
    public ushort features;  
    public uint  elementSize; 
    public uint  locks;  
    public IntPtr dataPtr;  
    public uint  elementCount; 
    public int  lowerBound; 
} 

Dann Marshal.AllocCoTaskMem() verwenden, um den Speicher zu erstellen. Fülle alle Daten aus und gib sie weiter.

+1

Alle Dokumente, die ich finden kann, scheinen anzuzeigen, dass die Interop-Ebene das Array zu einem Safearray marshalieren sollte – Steve