我有一个 C++ dll,它是 ADOBE Acrobat 的插件。它需要经常(来回)和 WPF 进程使用大量复杂的数据结构进行交谈。
关于什么可能是最好的方法的任何想法。需要一些长期且可维护的东西,换句话说,我会喜欢一些想法,这些想法可以让进程产生看起来像方法调用的东西,而一些基础设施部分则可以进行编组和调度。我已经尝试过 Windows 消息,但在 ADOBE 上遇到了一些冲突问题,也对导致 dll 让 adobe 加载 CLR 的任何事情不感兴趣。只有我想到的其他东西是命名管道或http。
提前致谢
3 回答
命名管道可以做到,但你不会感觉到只是调用函数。命名管道是相当低级的 IPC。其他 IPC 选项包括:
- Windows RPC,你肯定会感觉到只是调用函数。
- 在 WPF 应用程序中托管 COM 对象并从 Adobe 插件调用它怎么样?
我会选择 COM:
- 在 WPF 应用程序中实现接口
- 生成一个类型库(例如通过使用
regasm
) - 将 typelib 导入 C++ dll
- 交流
如果您需要双向通信,C++ dll 还可以实现一个 COM 接口,然后从 WPF 应用程序访问该接口。
这就是我用来将旧版 C++ 应用程序与新的 .NET 服务连接起来的方法,而且效果很好。最大的问题是找懂COM的人,好在这不需要对COM有深入的了解。
您对 COM 的提示非常有趣。我试图实现这个概念。我在我的 WPF CallDllFromWpf3Interface 项目中创建了一个接口:
using System.Runtime.InteropServices;
namespace CallDllFromWpf3Interface
{
[Guid("F6E0E2E8-CCC6-487B-8BF1-261265061E6A")]
public interface SetValueInterface
{
void SetValue(int value);
}
}
然后我使用 regasm 工具生成了 typelib:regasm CallDllFromWpf3Interface.exe /tlb
使用“oleview”工具,我可以看到类型库和界面。
下一步是创建一个名为“CallSetValueInterface”的 c++ dll 项目。
在我的 CallSetValueInterface.cpp 文件中,我写了以下几行:
#import "D:\Thomas\Programming\WPF\Basics\CallDllFromWpf\CallDllFromWpf3Interface\CallDllFromWpf3Interface\bin\Debug\CallDllFromWpf3Interface.tlb"
void
CallSetValueInterface::startAcq(void)
{
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
CallDllFromWpf3Interface::SetValueInterfacePtr Svip("f6e0e2e8-ccc6-487b-8bf1-261265061e6a");
Svip->SetValue(55);
Svip = NULL;
CoUninitialize();
}
成功构建 dll 项目后,我将“CallSetValueInterface.dll”复制到“CallDllFromWpf3Interface”项目中。
最后,我将 WPF 代码更改为:
#region SetValueInterface Members
public void SetValue(int value)
{
MyValue = value;
}
#endregion
[DllImport("CallSetValueInterface.dll", EntryPoint = "startAcq", ExactSpelling = true, SetLastError = true)]
public static extern void StartAcqFromDll();
private void Button_Click(object sender, RoutedEventArgs e)
{
StartAcqFromDll();
}
当调试器来到 StartAcqFromDll() 时,出现了一个错误对话框“CallDllFromWpf3Interface.exe 中发生了类型为 'System.Runtime.InteropServices.SEHException' 的未处理异常”。
有人知道出了什么问题吗?
问候,
托马斯·L。