2

我现在正在搜索和尝试各种解决方案大约两周,以使以下成为可能:将 32 位库和 C++/.NET 包装器移植到 64 位(用于 C++)和 AnyCpu(用于 .NET)。

有:

  • 一个 C++ 库,它公开了一个 C 风格的接口,进一步称为“大脑”(我们都这么称呼它)
  • 使用 The Base 的第二个 C++ 库 (DDC) 更像是它的包装器,因为它包含了一个非常好的接口
  • 一个 .NET 库 (DDN),它使用 The Base 并充当 C# 和 VB 的包装器
  • 一个 JAVA 库(DDJ)[不重要,我们有单独的开发来处理这个]
  • PYTHON 库 (DDP) [也不重要]

这些库非常庞大,有数千种结构和功能(与数据库和一些不同的以太网设备接口)。有很多我什至不知道为什么要保留在代码中的功能,但是要求就是要求,必须遵守...

整个驱动程序和数据库连接器只有 32 位配置。内部没有任何相关文档,并且必须修改大量代码(不是重写或重构,而是修改)。

所有结构都在 4 个字节上对齐,.net 和 C API 之间的编组在 32 位上工作正常。

新要求是创建 AnyCPU .NET 配置,根据运行 VB/C# 应用程序的系统分别使用 64 位和 32 位 Base。

到目前为止一切顺利 - DDC 与 The Base 配合得很好。但是当涉及到 DDN - 有很多 s### 发生:要与 Base 编组和解组的结构有一个 4 字节的包......因此,Base 结构的对齐方式已切换到32 位和 64 位均为 4 个字节(分别为 4 个和 8 个字节)。

我最初的计划是针对 32 位和 64 位配置分别对齐 4 和 8 字节,但是在与 Base C 包装器接口的 .NET API 中还有很多工作要做……调用和回调是分开的在不同的命名空间中,每个都包括各自的库,但结构很痛苦......

第二个计划是将所有内容与 4 或 8 对齐,但是有很多关于结构和一元运算符打包的警告......除了这些警告之外,没有什么好用的了。堆损坏,关机崩溃等。

第三种解决方案是切换回解决方案 1,并在两个命名空间(与 32 位 Base 库交互的命名空间和与 64 位 Base 库交互的命名空间)上创建具有适当包的结构

我将不胜感激任何反馈。如果有任何不清楚的地方,请随时询问更多信息。

谢谢你们!

4

1 回答 1

1

根据我的经验,将指针从/到非托管代码传递到托管代码是一个非常糟糕的主意。如果您使用回调,最终结果可能比预期的要差。您必须记住,.NET 对内存进行碎片整理,因此指针的物理地址可能会有所不同(因此您可以想象可能发生的事情)。


解决方案 A:让它变得简单,如果您想将非托管与托管混合使用,请使用非托管 C 托管的 C++(因此,没有任何 CPU 解决方案)。Oracle 数据访问是该解决方案的一个示例。


解决方案 B:将解决方案拆分为两个项目,一个是托管的,一个是非托管的。层之间共享的对象必须在非托管端。您必须忘记非托管项目和托管项目之间的回调。此解决方案用于 .NET 的 SQLite 驱动程序。

于 2013-06-01T21:14:05.953 回答