不同大小数据在DLL及与.NET间传递的优选方案问询
我需要在原生DLL之间、原生DLL与.NET程序集之间传递大小不固定的数据结构,希望找到一种实现成本低、bug最少的方式。由于这类操作很少发生,性能成本可接受(如500ms以内即可,当然越快越好)。
我正在开发一个.NET模块化应用,将通过P/Invoke与原生DLL(同样为模块化)通信。目前构思的架构(开发中)如下:
+-----------------------+ +----------------+ +---------------------+ | .NET/WPF application | 1 1 | Native DLL | 1 * | Native DLLs | +-----------------------+ <----> +----------------+ <----> +---------------------+ | GUI | | Interface to | | Module with various | +-----------------------+ | native modules | | responsibilities | +----------------+ +---------------------+
启动时,接口DLL会查询所有模块并请求信息,返回结果大小不固定(大致是包含可变长度文本等内容的结构数组),这些数据随后会传递给.NET应用作为处理中心。
.NET应用也可能向原生DLL发送大小可变的结构(如节点包含可变长度文本和图像的可变大小树),目前尚未确定,但可能性较大。
我正在寻找这类数据的交换方式。在.NET环境中这很简单,可传递包含string、字节数组等的List<T>——因为类、字符串和数组属于CLR,所有.NET程序集都能正确“解析”传递的信息。
但在C++中并不容易,需要考虑不同运行时、不同编译器等因素——按值传递“类”风险很高。
目前我考虑了以下方案(请注意我只是偶尔写C++,因此提出此问题):
二进制序列化
简而言之:DLL A将数据序列化为已知的二进制格式,把数据起始指针和长度传递给DLL B,后者将数据解码为自身的结构和类。DLL B与.NET程序集之间的传递方式同理。
优点:
- 实现相对简单
- 在固定数字字节序和文本编码的前提下,二进制兼容性较易实现
缺点:
- 易出错:容易引入难以检测的bug(如在很少使用的字段中)
- 需要双重实现:分别在C++和.NET中实现,并保持两者兼容
- 如需向前/向后兼容性,需额外手动实现(除非使用Google's Protobuf等序列化/反序列化库)
使用中间文本格式
简而言之:DLL A将数据序列化为JSON/XML,DLL B将数据反序列化为类/结构。DLL与.NET之间的传递同样简单。
优点:
- .NET中处理JSON和XML非常便捷
- 相对容易实现向前/向后兼容性
缺点:
- 速度明显慢于二进制序列化
- C++中处理JSON比.NET更困难
在原生C++领域,从实现难度、向前/向后兼容性及可靠性来看,上述哪种方法是首选?是否有我未考虑到的其他方式(比如COM)?
内容的提问来源于stack exchange,提问作者Spook

