gpt4 book ai didi

c# - 如何在C#中使用C++ DLL导出的接口(interface)指针

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:41:25 25 4
gpt4 key购买 nike

我有一个用 C++ 编写的 DLL,它导出一个函数 CreateRisk。该函数返回一个接口(interface)指针,如下所示:

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接口(interface)(这里省略实现)。

我想要的是在 C# 中调用函数 CreateRisk 并获取对 IRisk 的引用。

我在c#中定义了一个包装器接口(interface)

    [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 接口(interface),以便我可以在 C# 中调用 Calculate 方法?

我已经尝试过 Marshal.GetIUnknownForObjectInContext、Marshal.GetObjectForIUnknown,但无济于事。

我知道创建一个 COM 组件可以做到这一点。但是,COM 组件需要在系统中注册。我想避免那些麻烦,让C#直接使用C++ dll导出的接口(interface)。

附言:

以下是我的 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);
}

最佳答案

以下将起作用:

[DllImport("Risk.dll")]
extern static IRiskAssessment CreateRisk();

您需要将 GUID 添加到界面:

[Guid("your GUID goes here")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IRiskAssessment
{
[PreserveSig]
int Calculate(int i,double s);
}

显然,您需要在 C# 代码中使用与在 C++ 代码中使用的相同的 GUID!

更新

查看您的 C++ COM 对象实现,明显的错误在 QueryInterface 中。您不得为所有 GUID 返回 S_OK。只为您实现的接口(interface)返回 S_OK。为其他人返回 E_NOINTERFACE

关于c# - 如何在C#中使用C++ DLL导出的接口(interface)指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13741373/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com