【发布时间】:2019-04-10 20:57:06
【问题描述】:
我们有一个旧的 32 位 Visual Studio C# Windows Forms 解决方案,我们希望从现在开始以 64 位编译它。不幸的是,我们的应用程序使用了一些仅在 32 位版本中可用的外部 dll-s(用于扫描仪、相机等)。 Accessing 32-bit DLLs from 64-bit code 并不简单,尤其是当我们还想处理那些 dll-s 引发的事件时。我们在这方面的知识不足以创建基于本文的实现,因此我们正在寻找更详细的说明或示例。
我们的第一次尝试是基于this article。我们将第三方 dll-s 包装到一个后期绑定的 32 位 COM 服务器中,并从我们的 64 位应用程序中使用它,如此处所述(经过必要修改,因为我们必须交换 32 位和 64 位的角色) .此尝试成功,但未完成,因为此解决方案不会将事件从 COM 服务器传递到 64 位客户端。所以我们开始关注事件。我们发现了很多文章和例子处理由 COM 对象引发的消费事件,但没有一个为我们提供完整的解决方案。一部分源代码专门处理客户端,或者专门处理服务器,但它们彼此不兼容,或者与我们的环境(WinForm、c#)不兼容。
例如,
- this answer 告诉我们如何制作一个向 VBA 客户端公开 .NET 事件的 COM 服务器,但我不知道如何从 c# 客户端使用它。
- 相比之下,this article 为现有的 COM 服务器提供了一个运行良好的 C# 客户端,但没有说明如何制作这样的 COM 服务器(这个 COM 服务器与前面的示例明显不同)
- this answer 没有透露解决方案的任何细节。
- This article 用于 c++ 而不是 c#。
- This answer 指的是 this article,但后者再次使用 VB 客户端而不是 c#。
- This article 以无法追踪的方式混合不同的东西。
也许我们可以通过一些努力来使用其中的一些,但是哪些以及如何使用?
编辑
现在我倾向于创建一个混合解决方案:对于从 32 位 COM 对象到调用者 64 位应用程序的反向通信,我的最新想法是将一个命名管道服务器放入 64 位应用程序和一个命名管道客户端进入 COM 对象,并且每次在 COM 对象中引发事件时,它都会向命名管道服务器发送一个命名管道消息。我为此找到的代码可用 here(项目 CSNamedPipeServer 和 CSNamedPipeClient)。
【问题讨论】:
-
这个 DLL 是生成可视化组件,还是只是将事件生成回您的代码? 32 位 => 64 位是一堆蠕虫(正如您所发现的),因为它需要您跨越进程边界(32 位是 64 位窗口中的单独虚拟环境)。您是否尝试过 C# 中的 32 位包装器,与您的 64 位程序进行进程外对话?
-
你不是在几天前问过这个问题吗(并删除了它,连同它的 cmets)?
-
@SimonMourier 差不多。问题是一样的,但现在问题不同了,而且(希望)更详细。
-
如果需要,我可以提供一个 C# 示例,其中包含一个带有事件的 64 位 COM 服务器和一个可以工作的 32 位 COM 客户端。
-
@SimonMourier 酷!我期待您的解决方案。
标签: c# winforms event-handling com-interop