使用C#WPF组件扩展C ++ Win32应用程序

时间:2010-09-17 10:00:00

标签: c# c++ wpf winapi com-interop

我需要向C ++ Win32应用程序添加一个新组件(没有CLR支持),我想在C#中实现新组件并使用WPF。这个新组件基本上是一个带有一些控件的窗口,我需要从Win32应用程序菜单中的一个选项快速启动。新组件和现有应用程序共享一些int值,两者都可以修改这些值,另一个应该通知更改。

实现这一目标的最佳方式是什么?

由于

4 个答案:

答案 0 :(得分:1)

你有没有看到关于这个主题的MSDN docs

粗略读取意味着如果不在C ++代码上启用/clr,这是不可能的。如果你能够转移到这个模型,那么你想要的东西似乎可以。

btw我不会在共享数据的托管/非托管边界的两端实现更新/信令代码。确定数据所在的位置,并使该代码提供a)线程安全访问器和b)“更新事件”连线,这些连接由需要编写数据并了解更新的人员使用。

查看Observer pattern,了解如何向多个消费者实施通知。对于您的案例而言,这可能有点过分,但有用的背景。

编辑:

在你获得两个模块的同时,对事件通知设计的讨论似乎为时过早。如果你真的无法使用/ clr构建本机代码,那么我没有看到如何在没有单独的进程的情况下使用WPF组件,从而导致交互和性能受到影响的复杂性。你能在本机代码中重新实现这个WPF功能吗?

另一方面 - 如果你打算为这个代码库制作更多的mod,也许值得考虑将本机代码移植到/ clr-ready有多么困难。内联汇编程序不会阻止使用/ clr,但它确实会让它变得更难,因为我相信你已经看到了here。我的猜测是,这比外部连接WPF代码要少。

此时阻力最小的路径可能是在本机代码中复制WPF组件。长期考虑将应用程序转换为/ clr的痛苦可能会提供更好的基础。对不起,没有简单的答案。

答案 1 :(得分:1)

如果要在不更改C ++编译的情况下执行此操作,可以考虑通过COM调用.NET程序集。 MSDN描述了如何expose .NET Framework Components to COM

我这样做的方式基本上是:

  1. 在C#
  2. 中创建一个COM友好类和接口
  3. 从DLL导出TLB
  4. GAC DLL
  5. 使用regasm.exe注册DLL
  6. 将TLB导入我的C ++代码

  7. 使用我的C#类__uuid的CoCreateInstance
  8. 但是还没有尝试使用UI组件执行此操作。如果WPF表单是一个模态对话框,你应该没问题。如果没有,那么我不知道WPF是否会对您的消息循环感到满意;你可能需要给它一个单独的线程,以便它可以运行自己的循环。

答案 2 :(得分:0)

实现此目的的一种方法是将C ++应用程序编译为C ++ / CLI应用程序。一旦它成为C ++ / CLI应用程序,您就可以轻松地混合托管代码和本机代码,甚至可以轻松地与托管组件进行通信。

答案 3 :(得分:0)

我宁愿使用C ++ / CLI作为粘合层而不是混淆COM,也不需要将整个应用程序重新编译为C ++ / CLI。

这意味着:

  1. 编写您想要的C#代码。
  2. 编写一个瘦C ++ / CLI包装器。这可以引用(即动态链接)到C#app。它所做的只是在.NET API周围公开一个原生API。这需要一些习惯,但你可以在这里做相当复杂的事情,包括通过marshal_as相当花哨的自动互操作。你将把它编译成一个dll - 一个混合模式的DLL。
  3. 您的主应用程序现在动态链接到混合模式DLL,并包含其API的标头。它可以照常调用函数。
  4. 这比COM好一点,我认为:它不需要GAC,如果性能不重要,它具有较低的开销,并且交换复杂的数据结构,包括回调和放大器。通过添加自定义marshal_as模板/重载,可以非常干净地使用深度对象图(虽然这里有一个学习曲线)。