関数 CreateRisk をエクスポートする C++ で記述された DLL があります。この関数は、次のようにインターフェイス ポインターを返します。
extern "C"
{
__declspec(dllexport) IRisk* __stdcall CreateRisk()
{
return new Risk();
}
}
IRisk は IUnknown から派生し、独自のメソッド Calculate を持っています。
class IRisk: public IUnknown
{
public:
virtual int __stdcall Calculate(int i,double s) = 0;
};
クラス Risk は、IRisk インターフェイスを実装します (実装はここでは省略されています)。
私が望むのは、C# で関数 CreateRisk を呼び出し、IRisk への参照を取得することです。
C# でラッパー インターフェイスを定義しました
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IRisk
{
[PreserveSig]
int Calculate(int i,double s);
}
そして、C#にdllエントリを追加しました
[DllImport("Risk.dll")]
extern static IntPtr CreateRisk();
C# で CreateRisk を呼び出して、IntPtr の値の型を取得できます。C# で Calculate メソッドを呼び出せるように、IntPtr を c# IRisk インターフェイスにマーシャリングする方法はありますか?
Marshal.GetIUnknownForObjectInContext,Marshal.GetObjectForIUnknown を試しましたが、役に立ちませんでした。
COM コンポーネントを作成すればそれができることはわかっています。ただし、COM コンポーネントをシステムに登録する必要があります。これらの問題を回避し、C# で C++ dll によってエクスポートされたインターフェイスを直接使用できるようにしたいと考えています。
PS:
以下は、私の Risk クラスの実装です。
class IRisk : public IUnknown
{
public:
virtual int __stdcall Calculate(int i,double y ) = 0;
};
class Risk:public IRisk
{
int count;
public:
Risk();
virtual int __stdcall Calculate( int i ,double y);
virtual ULONG __stdcall AddRef();
ULONG __stdcall Release();
HRESULT __stdcall QueryInterface(const IID& riid,void **ppvObject);
};
Risk::Risk(){
count=0;
}
ULONG __stdcall Risk::AddRef()
{
return ++count;
}
ULONG __stdcall Risk::Release()
{
return --count;
}
HRESULT __stdcall Risk::QueryInterface(const IID& riid,void **ppvObject) {
*ppvObject=this;
AddRef();
return S_OK;
}
int __stdcall Risk::Calculate(int i ,double y) {
return (int)(i+y);
}