1

インターフェイスのメソッドが存在する ATL COM サーバーがあります。

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

この関数の MIDL は次のようになります。

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

tlbimp を使用してこのプロジェクトから tlb をインポートするので、ネイティブ配列を使用できます。次に、次のようにC#から呼び出します

 m_ServerWrapper.RUN(iInputs.Length,ref iInputs)

ここで、Inputs は既に割り当てられており、C# プログラム内から別の COM オブジェクトで埋められています。ここで、C++ ラッパーをBadPtr呼び出すと、セーフ配列があり、配列から後続の COM オブジェクトへの呼び出しがCWrapper::RUN失敗し、配列が最終的な dll に到達しません。未割り当てと表示されます。誰かが私が間違っていることについて何か手がかりを持っていますか? ありがとう

編集:配列はC#で問題なく見えると述べるべきでした。

EDIT2: デバッガーは のiDatasafearray を示していますIDispatch* = 0x0000000 <Bad Ptr>, 5, 0x0000000 <Bad Ptr>({lpvtbl = 0xblahblah},...。それで、私の情報の一部がそこに届いているようです。

4

1 に答える 1

0

通常のC#配列は、SAFEARRAYと同じではありません。私はあなたがあなた自身を作らなければならないと思います:

[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;  
}

次に、Marshal.AllocCoTaskMem()を使用してメモリを作成します。すべてのデータを入力してから渡します。

于 2009-03-27T22:08:54.190 に答える