【问题标题】:How to create a Callback from C#/.NET via COM to C++?如何通过 COM 创建从 C#/.NET 到 C++ 的回调?
【发布时间】:2014-09-06 00:57:21
【问题描述】:

我目前正在使用 C#/.NET 库,该库使用 C++ 的 COM 接口。就像一个简单的虚构示例来说明我目前正在做的事情:

我有一个声明和导出 COM 接口的 C#/.NET 组件。

[Guid("example-0000-0000-0000-0000000000000")]
public class MyObj : IMyObj
{
    void DoSomething(string someArgument);
}

现在我导出一个类型库,该类型库导入到我的 C++ 应用程序中:

#import "MyObj.tlb" named_guids auto_rename

void someFunc()
{
    MyObjPtr myObj;
    myObj.CreateInstance(CLSID_MyObj);
    myObj->DoSomething(_bstr_t(L"foo"));
    // ...
}

实际上,C#/.NET 组件具有许多接口和方法。它以多线程方式从 C++ 中使用。

一切都很好,但我想为 C#/.NET 库启用日志记录。 C#/.NET 库的内部应该能够将日志消息发送回 C++ 应用程序,以便使用那里已经存在的日志记录环境来写入日志消息。

[C++ 日志系统]

为这种情况创建一种回调的最佳方法是什么?

回调应该只接受一个简单的字符串。例如:

public interface ILogger {
    void Write(string message);
}

如何在 C++ 端实现这一点?

(同时在这里回答:How to implement COM callback interface in C++, from C# assembly, using #import and tlb file?

【问题讨论】:

    标签: c# c++ .net visual-c++ com


    【解决方案1】:

    我知道 COM 提供了一种事件处理模式,但公平地说,我一直无法理解它。快速搜索让我找到了this 页面,这似乎是一个很好的解释。

    就我个人而言,我不会让事情变得比必要的更复杂;我想如果你让你的.NET代码实现RegisterLogger(ILogger instance)/UnregisterLogger(ILogger instance),并将ILogger接口标记为双接口(即它继承自IDispatch),那么你的.NET代码可以使用它来记录消息- 但请确保您使用后期绑定的方式来调用它 - 例如见here

    在C++端,定义一个继承自IDispatchILogger接口,这样就可以 与后期绑定一起使用,并让您的 C++ 代码调用 .NET RegisterLogger() 方法,传入您自己的ILogger 实现。 由于使用后期绑定,C++ ILogger 接口不需要知道 .NET 端,它只需要匹配的方法签名。

    【讨论】:

    • 那么,我可以在 C++ 中从ILogger 接口派生并将对象指针传递给 COM 接口吗?所有权情况如何?这个 C++ 对象是 C++ 应用程序拥有的,还是 COM/C#/.NET 部分处理这个对象?
    • 1) 不,有 2 个 ILogger 接口,一个在 .NET 中,一个在 C++ 中。只要它们都从 IDispatch 派生,共享相同的方法签名并通过后期绑定调用,每一方都可以使用自己的 ILogger 接口版本,同时仍然兼容。 2) 所有权的处理与所有 COM 对象一样,实例化端(您的 C++ 代码)仍然是所有者,而客户端(您的 .NET 代码)使用 IUnknown 的 AddRef 和 Release 来指示所有者是否可以清理实例。跨度>
    • 澄清一下,您并不需要 IDispatch 接口(即后期绑定),但是接口的内存布局必须在两边相同- 即您需要.NET 代码声明接口并让C++ 端导入它。想一想,您可能已经在代码中的其他任何地方都这样做了,这个想法还不错;)
    • 非常感谢您的答复,并为我的延误感到抱歉。我会尽快尝试您的解决方案。
    • 它确实有效,但它没有回答我的第二个问题。在不使用 ATL 或 MFC 的情况下实现这样的 COM 接口并不是那么简单。但幸运的是,C# 组件只对 IUnknown 接口感兴趣,而不对 IDispatch 接口感兴趣。因此,这样的类的实现很简单。
    猜你喜欢
    • 1970-01-01
    • 2010-11-05
    • 1970-01-01
    • 2012-06-09
    • 2012-12-08
    • 1970-01-01
    • 2015-02-22
    • 1970-01-01
    • 2011-10-15
    相关资源
    最近更新 更多