使用 x86/x64 C API 的 C# AnyCPU 库 - 打包结构、调用和回调
Posted
技术标签:
【中文标题】使用 x86/x64 C API 的 C# AnyCPU 库 - 打包结构、调用和回调【英文标题】:C# AnyCPU library using x86/x64 C API - packing structures, calls and callbacks 【发布时间】:2013-04-19 14:39:08 【问题描述】:我现在正在搜索和尝试各种解决方案大约两周,以实现以下目标:将 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 位上可以正常工作。
新要求是根据运行 VB/C# 应用程序的系统创建 AnyCPU .NET 配置,分别使用 64 位和 32 位 Base。
到目前为止一切顺利 - DDC 与 The Base 配合得很好。但是当涉及到 DDN - 有很多 s### 发生:要与 The Base 编组和解组的结构有一个 4 字节的包...... 因此,对齐32 位和 64 位的基本结构已切换为 4 个字节(分别为 4 个和 8 个字节)。
我最初的计划是针对 32 位和 64 位配置分别对齐 4 和 8 字节,但是在 .NET API 与 Base C 接口方面还有很多工作要做包装器...调用和回调在不同的命名空间中分离,每个命名空间都包含各自的库,但是结构很痛苦...
第二个计划是将所有内容与 4 或 8 对齐,但有很多关于结构和一元运算符打包的警告......除了这些警告之外,没有什么好用的了。堆损坏、关机崩溃等。
第三种解决方案是切换回解决方案 1,并在两个命名空间(与 32 位 Base 库交互的命名空间和与 64 位 Base 交互的命名空间)上创建具有适当包的结构图书馆)
如果有任何反馈,我将不胜感激。如果有任何不清楚的地方,请随时询问更多信息。
谢谢大家!
【问题讨论】:
你在这些结构中有什么指针吗?您能否发布一些来自底层 C 代码的示例结构? 存在带有指针的结构(因为存在各种数据类型的数组)。此外,联合被广泛使用,即结构内的成员属于联合类型(因数据库字段类型而异)。这些结构没有对齐,因为它们的成员(有时是数十个成员)按含义分组并最终包含在 ifdef 中。不过,这里有一个示例结构:struct test_ byte state; TCHAR* driverName; DWORD driverId; uint objectHandle; DWORD* results; Type resultDataType; // this is a union bool whatEverOtherElements; test;
【参考方案1】:
根据我的经验,将指针从/到非托管代码传递到托管代码是一个非常糟糕的主意。如果您使用回调,最终结果可能比预期的要差。您必须记住,.NET 会对内存进行碎片整理,因此指针的物理地址可能会有所不同(因此您可以想象可能发生的事情)。
解决方案 A: 简单来说,如果您想将非托管与托管混合使用,请使用非托管 C 托管的 C++(因此,没有任何 CPU 解决方案)。 Oracle 数据访问就是这种解决方案的一个示例。
解决方案 B: 将解决方案拆分为两个项目,一个是托管的,一个是非托管的。层之间共享的对象必须在非托管端。您必须忘记非托管项目和托管项目之间的回调。此解决方案用于 .NET 的 SQLite 驱动程序。
【讨论】:
抱歉这个迟到的答案...这不是我的代码,我不得不将它从 wow64 移植到本机 x64... 不是我做的初始架构,我的建议在过程中被忽略了项目启动。我的解决方案是在托管/非托管代码之间交换句柄,每个函数接收句柄以返回状态代码(每个项目,在一个输出数组和全局中)。以上是关于使用 x86/x64 C API 的 C# AnyCPU 库 - 打包结构、调用和回调的主要内容,如果未能解决你的问题,请参考以下文章
关于VS项目平台的x86,x64,Any CPU以及Debug和Release的区别