使用x86/x64 C API的c# AnyCPU库-打包结构,调用和回调

C# AnyCPU library using x86/x64 C API - packing structures, calls and callbacks

本文关键字:结构 包结构 回调 调用 x64 x86 API AnyCPU 使用      更新时间:2023-10-16

我正在搜索和尝试各种解决方案,现在像两个星期,使以下可能:端口32位库和c++/。.NET包装为64位(用于c++)和AnyCpu(用于。NET)。

有:

  • 一个c++库,它公开了一个C风格的接口,进一步称为"大脑"(我们都这么称呼它)
  • 是第二个使用Base的c++库(DDC),它更像是一个包装器的方式,它包装了一个非常漂亮的接口
  • 一个。net库(DDN),它使用Base,并像包装器一样为c#和VB
  • 一个JAVA库(DDJ)[不重要,我们有单独的开发来
  • PYTHON库(DDP)[也不重要]

库是巨大的,有成千上万的结构和函数(与数据库和一些不同的以太网设备接口)。有很多功能,我甚至不知道为什么要保存在代码中,但需求就是需求,必须遵守…

整个驱动程序和数据库连接器只有32位配置。里面没有任何相关的文档,很多代码需要修改(不是重写或重构,而是修改)。

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

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

到目前为止一切顺利- DDC与The Base工作得很好。但是当涉及到DDN时,就会发生很多问题:要用Base编组和解组的结构有一个4字节的包……因此,对于32位和64位,Base结构的对齐已切换为4字节(分别为4个8字节)。

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

第二个计划是将所有内容与4或8对齐,但是关于结构体和一元操作符的包装有很多警告……除了这些警告,再也没有什么管用的了。堆损坏,关机崩溃等。

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

我将非常感谢任何反馈。如果有任何不清楚的地方,请不要犹豫,询问更多的信息。

谢谢大家!

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


解决方案A:让它变得简单,如果你想混合非托管和托管,用c++管理使用非托管C(所以,没有任何CPU解决方案)。Oracle Data Access就是一个例子。


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