I have a DLL written in C++, which exports a function CreateRisk. The function returns an interface pointer, as follows:
extern "C"
{
__declspec(dllexport) IRisk* __stdcall CreateRisk()
{
return new Risk();
}
}
IRisk is derived from IUnknown and has a custom method Calculate:
class IRisk: public IUnknown
{
public:
virtual int __stdcall Calculate(int i,double s) = 0;
};
the class Risk implements IRisk interfaces (the implementation is omitted here).
What I want is to call the function CreateRisk in c# and obtain a reference to IRisk.
I defined a wrapper interface in c#
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IRisk
{
[PreserveSig]
int Calculate(int i,double s);
}
and I added a dll entry in C#
[DllImport("Risk.dll")]
extern static IntPtr CreateRisk();
I can call CreateRisk in C# and obtain a value type of IntPtr. Is there any way to marshal the IntPtr to the c# IRisk interface so that I can call the Calculate method in C#?
I have tried Marshal.GetIUnknownForObjectInContext,Marshal.GetObjectForIUnknown, but to no avail.
I know creating a COM component can do it. However, COM component needs to be registered with the system. I want to avoid those troubles and let C# use the interface exported by the C++ dll directly.
PS:
The following is my Risk class implementation:
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);
}