c# - 来自 .NET Framework >= 4(64 位)的 native ANSI C 库

标签 c# c native ansi-c

我有一个 C# 应用程序,它 (P/) 调用制造商提供的 ANSI C 库,以通过网络访问 RFID 读取器。 如果我手动将平台设置为 x86,这对于 .NET Framework 版本 2.0 至 4.5 来说绝对可以正常工作。

另一方面,如果平台设置为 64 位,则它仅适用于 .NET Framework 版本 <= 3.5。 我得到的错误代码被定义为“InvalidHandle”,其中句柄是由识别读者的库给出的一个 int 。 我不明白框架版本会对 native 库产生什么影响,尤其是在 64 位平台上。

我观察到的情况,尽管我不确定它是否相关: - 失败时,句柄长度为10位,有时为正,有时为负 - 成功的情况下,句柄长度为9位,始终为正

根据这一观察,我尝试了其他数据类型(int、uint、long、ulong),但没有成功(并且行为相同)。

组件的“设置”由多个步骤(方法调用)组成,它们是: 1. Init(我从中获取句柄的地方) 2.SetChannel(以一个字节为参数) 3. SetAddress(采用包含 IP 和端口的连接字符串作为参数) 4. 打开() 注意:所有这些方法都将句柄作为 int 输出参数。 因为SetAddress方法失败,当Init和SetChannel也将句柄作为参数但不这样做时,我怀疑它可能与字符串有关,尽管我还没有找到任何证据支持这个理论。

不幸的是,该文档几乎不存在。

因此,任何想法都将受到高度赞赏。 如果您需要更多信息,我很乐意提供。

问候,

帕斯卡

[DllImport("/x64/BLUEBOXLib.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
static extern int BLUEBOX_Init(out int Handle);

[DllImport("/x64/BLUEBOXLib.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
static extern int BLUEBOX_SetAddress(ref int Handle, byte Address);

[DllImport("/x64/BLUEBOXLib.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
static extern int BLUEBOX_SetChannel(ref int Handle, String Channel, String Settings);

摘自 BLUEBOXLib.h 文件:

BLUEBOXLib_API BLUEBOX_ErrorCodes __stdcall BLUEBOX_Init (BLUEBOX_Handle *Handle);

BLUEBOXLib_API BLUEBOX_ErrorCodes __stdcall BLUEBOX_SetChannel (BLUEBOX_Handle *Handle, char *Channel, char *Settings);

BLUEBOXLib_API BLUEBOX_ErrorCodes __stdcall BLUEBOX_SetAddress (BLUEBOX_Handle *Handle, unsigned char Address);

typedef int BLUEBOX_Handle;

最佳答案

    typedef int BLUEBOX_Handle;

这是一个问题,您无法修复这个问题,因为它没有出现在您的代码中。实现句柄的方法有多种,但它们基本上分为两个不同的类别。它要么是内部数组的简单索引,要么是普通指针。当您看到“10 位数字长,有时是正数,有时是负数”时,则 99% 的可能性是指针。

该指针在 64 位模式下占用 8 个字节,它无法容纳在 int 中。是的,有时这仍然有效,这取决于操作系统和测试程序的简单性。在 Vista 或 Win7 的 x64 版本上,64 位指针仍然可以意外地装入 32 位值,分配通常发生在较低的 2 GB 地址范围中。您在 Win8 上成功的几率为零,这也暗示了为什么它似乎可以在 .NET 3.5 上工作。是的,负值不起作用,因为当 C 代码将句柄转换为真实指针类型时,它们会进行符号扩展,从而产生垃圾指针值。

您无法修复此错误,必须由供应商修复。他们必须将 typedef 更改为 void*,现在您可以使用 IntPtr 了。给他们打电话。如果它们没有响应,请考虑在与您互操作的单独的 32 位帮助程序进程中运行此代码。

关于c# - 来自 .NET Framework >= 4(64 位)的 native ANSI C 库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26932293/

相关文章:

c# - visual studio 2012 C#的内存诊断工具

c# - Entity Framework 5 不清除导航属性

c - 为什么线程在 linux 中没有以正确的优先级运行

c++ - 尝试使用 Android-NDK 生成 so 文件时,未在此范围内声明“runtime_error”

java - 如何使用Maven处理跨平台(Windows + Linux)Java Native Interface项目?

c# - 替换Azure存储中的内容

java - java中如何保存从jni返回的void*以供以后使用

arrays - 将文件中的行复制到 char *array[]?

javascript - react native (ios)。 "saveToCameraRoll"错误 - "PHPhotosErrorDomain error -1"

c# - 如何检查Word文件是否包含文本C#