WCF 服务调用具有复杂数据类型的非托管 c++ dll

Posted

技术标签:

【中文标题】WCF 服务调用具有复杂数据类型的非托管 c++ dll【英文标题】:WCF Service calling a unmanaged c++ dll which has complex datatypes 【发布时间】:2014-07-17 16:02:28 【问题描述】:

首先,如果我问了已经有答案的问题,我很抱歉。我做了一些研究,但我无法得到我想要的。我是 WCF 服务的新手,所以请多多包涵,所以情况是这样,我有一个非托管的 c++ dll,它具有复杂的数据类型,例如结构、联合,也有一些用户定义的数据类型。我需要的是从 wcf 服务(c#)连接这个非托管 c++。我有两个选择 1. 将非托管 c++ dll 的复杂类型编组为 c# 类型。 2. 创建另一个非托管 c++ dll,它接受来自我的 wcf 服务的基本数据类型,并尝试将这些基本数据类型映射到当前 c++ dll 中的复杂数据类型。

我想知道哪个是更好的解决方案,我也想知道如何完成第二个选项。如果我错了,请纠正我。谢谢

【问题讨论】:

【参考方案1】:

这取决于您的数据类型有多复杂:如果数据类型不是很复杂,请使用第一种;如果非常复杂,例如结构数组,您可能需要使用第二个。

对于第一种方法,实现很简单,您只需要确保托管端(C#)和非托管端(原生 C++)中的数据类型具有相同的布局,这个 MSDN Marshaling Data with Platform Invoke 给出了如何去做吧。它很容易实现,但很难调试。例如,如果 C# 和 C# 中的 struct 有非常小的差异,例如 C# struct 中的 char 字段映射到 C++ 中的 int 字段,您的程序就会崩溃并且没有详细信息。 marshaller 就像一个黑匣子,你必须阅读大量文档才能了解里面发生了什么。这种方法称为显式 PInvoke

对于第二种方法,首先是混合 C++(C++\CLI) DLL 项目,而不是原生项目。 C++/CLI 可以访问本机资源和托管资源,因此可以在此处用作桥梁。基本,您需要在 C++\CLI 中为原生 C++ DLL 实现一个包装器,会有很多实现工作,但您知道发生了什么并且更容易调试。这种方法称为 C++ 互操作(隐式 PInvoke)。

正如MSDN 所说:建议使用 C++ 互操作而不是显式 PInvoke,因为它提供了更好的类型安全性,实现起来通常不那么乏味,如果修改了非托管 API,则更宽容,并且可以实现无法实现的性能增强显式 PInvoke。

【讨论】:

以上是关于WCF 服务调用具有复杂数据类型的非托管 c++ dll的主要内容,如果未能解决你的问题,请参考以下文章

使用具有复杂对象的 KSoap2 调用 WCF 服务。 WCF 接收空值

c# - 如何调用分配输出缓冲区以在c#中返回数据的非托管c++函数?

调用使用 C# 返回结构数组的非托管 dll 函数

具有 CORS 和基本身份验证支持的 WCF 自托管数据服务

为非托管 C++ 客户端创建 WCF 服务

WCF 托管在 IIS 中,连接到具有集成安全性的数据库时出现问题