3

IntPtrパラメータを必要とするインターフェイス メソッドを呼び出すにはどうすればよいですか? 私のメソッドが を必要とする場合、これはうまく機能しますがstring、 が必要な場合はそうではありませんIntPtr。C# でのインターフェイスの例を次に示します。

[
    Guid("etc-etc-etc"),
    InterfaceType(ComInterfaceType.InterfaceIsIDispatch),
    ComVisible(true)
]
public interface ICallback
{
    [DispId(1)]
    void CallbackWithString( string value );

    [DispId(2)]
    void CallbackWithHandle( IntPtr value );
}

このインターフェイスから C# で COM クラスを派生させ、そのディスパッチを C++ アプリケーションに (COM 経由で) 渡します。後で、その C++ アプリケーションは、そのディスパッチでメソッドを呼び出して、C# アプリケーションに通知を返します。

これは機能します:

CComPtr<IDispatch> obj;      // My C# COM interop object, stored in my C++ app
VARIANT arg;

arg.vt = VT_BSTR;
arg.bstrVal = myString;
obj.InvokeN( L"CallbackWithString", &arg, 1 );

これは機能しません:

arg.vt = VT_HANDLE;          // I also tried VT_BYREF, VT_VOID|VT_BYREF, and VT_INT_PTR
arg.byref = myHandle;
obj.InvokeN( L"CallbackWithHandle", &arg, 1 );

「機能しない」とは、関数が呼び出されないことを意味しますが、例外は発生しません。

IntPtrCOM 相互運用機能を介して送信することは可能ですか? もしそうなら、どのように?

4

1 に答える 1

1

それは VT_HANDLE ではなく、OleCtl.h からのハックです。CLR の SSCLI20 バージョンには、clr/src/vm/olevariant.cpp にバリアント マーシャリング コードがあります。VT_INT を IntPtr に変換します。ただし、これは 32 ビット タイプです。これを 64 ビット コードで動作させる必要がある場合は、VT_I8 が必要になると思います。

于 2013-05-29T23:39:22.310 に答える