我有一个用 C++ 编写的 DLL,它导出一个函数 CreateRisk。该函数返回一个接口指针,如下所示:
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 的值类型。有没有办法将 IntPtr 编组到 c# IRisk 接口,以便我可以在 C# 中调用 Calculate 方法?
我试过 Marshal.GetIUnknownForObjectInContext,Marshal.GetObjectForIUnknown,但无济于事。
我知道创建一个 COM 组件可以做到这一点。但是,COM 组件需要向系统注册。我想避免这些麻烦,让C#直接使用C++ dll导出的接口。
PS:
以下是我的风险类实现:
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);
}