从未托管的C++调用托管代码(C#)的最佳方法

4
我们已经开发了一个由C#开发的对象集合的软件架构。它们广泛使用事件来通知客户端状态等方面的变化。
最初的意图是通过COM互操作服务让遗留代码使用这些托管对象。在设计规范中编写这个很容易,但我发现实际实现起来更加棘手。我花了很多时间搜索关于使用这种方法处理事件的好样例。在我们走这条路之前,我想确保COM互操作是允许遗留代码调用我们的新代码的最佳方式。
看起来有几种不同的选择:1)COM互操作,2)编写非托管包装器类,3)使用/clr编译器开关来启用对托管对象的调用,4)使用某种反向pInvoke调用。我有遗漏的吗?
每个选项都有其优点和缺点,我想知道最好的方法是什么。以下是每个选项的具体问题/评论:
1. COM互操作 - 似乎事件处理是一道难关。我们使用具有可变类型作为参数的事件。事件参数可能具有事件ID和对象。根据事件ID,对象将是某种类型。这可以通过COM互操作处理吗?暴露的许多对象都具有属性。您无法在接口中声明属性,因此所有属性都需要相应的get/set方法。
2. 编写非托管包装器 - 我假设这意味着使用/clr选项创建DLL以允许创建和调用托管对象并公开非托管对象。这些非托管对象的客户端会是什么?我以前没有做过这个。这样做有什么好处/坏处?
3. 使用/clr开关 - 我理解这意味着添加对托管对象的支持。这种方法的缺点是什么?此选项是否支持上述事件?我们可以说,“这是托管库。请在您的遗留代码中使用/clr编译器选项并开始使用吗?”我不知道这样做的后果。有关如何解决此问题的良好示例吗?(我确定有,我只是没找到)
4. 使用反向pInvoke - 我不确定这将如何工作,但根据我所能找到的信息,这不太可能是一个有效的解决方案。
那么,决策树看起来像什么,以找到正确的方向?谢谢。

还有一种选择,即通过CoreRT将C#代码编译为本机代码并直接调用它(请参见此处)。 - Fabian
1个回答

1

我认为你的初始解决方案是最好的。COM互操作性稳定且文档合理。您需要做的就是确保所有可能从给定事件处理程序弹出的不同事件对象实现相同的COM可见基本事件对象接口(具有事件类型ID等)。从那里开始,各个对象可以实现任何其他接口,您的非托管代码可以根据您想要定义的任何标准QI正确的“详细”接口。这真的不难。请查看this CodeProject文章,其中包括非托管事件处理程序的端到端示例。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接