[英]FTDI library platform differences between Mac and Windows when using JNA
我目前正在开发一个 Java 应用程序,该应用程序使用 JNA 访问一些 FTDI 库,包括 D2XX 和 LibFT4222。 我已经使用 JNAerator 创建了使用的 JNA。 这在 Windows 平台上都可以正常工作。 然而,当我尝试在 Mac 上运行该软件时,我遇到了 LibFT4222 的问题。
FT_OpenEx 在 D2XX 中似乎工作正常,导致没有错误代码,我也可以检查其返回的描述,看到它被列为“FT4222 A”。 我还能够在不返回意外错误代码的情况下执行其他功能(例如关闭它两次,第一次没有错误代码,第二次产生预期的错误代码)。 但是,当在 D2XX 创建的 Handle(例如 FT4222_I2CMaster_Init、FT4222_GetVersion 或 FT4222_GetClock)上尝试使用 LibFT4222 进行任何操作时,它会产生错误代码 1000 FT4222_DEVICE_NOT_SUPPORTED。
我尝试过使用生成的 JNA 代码,例如将 FT HANDLE 类型从 PointerByReference 更改为 IntByReference,并且可以像以前一样在 Windows 上正常工作,但似乎仍然无法在 Mac 上工作。
使用 FTDI 提供的示例 C 文件的修改版本(使用相同的 LibFT4222.dylib),相同的逻辑可以正常工作,所以我知道它可以在 Mac 上正常工作。 如前所述,上述所有内容在 Windows 上都没有问题。
任何人都可以提供有关 Mac OSX 和 Windows 之间可能导致这种行为的差异的任何见解吗?
编辑以包含代码,示例 Java 代码(在这种情况下,描述将是“FT4222 A”,而 OpenEx 似乎可以正常工作)这适用于 Windows,但在 Mac 上 FT4222_I2CMaster_Init 返回 1000:
Memory memory = new Memory(16);
memory.setString(0, "FT4222 A");
PointerByReference handle = new PointerByReference();
Ftd2xxLibrary.FT_OpenEx(new PVOID(memory),
Ftd2xxLibrary.FT_OPEN_BY_DESCRIPTION, handle);
FT4222Library.FT_HANDLE ftHandle = new FT4222Library.FT_HANDLE(handle.getValue());
logger.warn("init" + FT4222Library.FT4222_I2CMaster_Init(ftHandle, (int) 100));
FT_OpenEx 在哪里(由 JNAerator 自动生成):/**
* Original signature : <code>FT_STATUS FT_OpenEx(PVOID, DWORD, FT_HANDLE*)</code><br>
* <i>native declaration : line 336</i>
*/
public static native NativeLong FT_OpenEx(Ftd2xxLibrary.PVOID pArg1, int Flags, PointerByReference pHandle);
其中 FT4222_I2CMaster_Initis(由 JNAerator 自动生成):
/**
* FT4222 I2C Functions<br>
* Original signature : <code>FT4222_STATUS FT4222_I2CMaster_Init(FT_HANDLE, uint32)</code><br>
* <i>native declaration : line 338</i>
*/
public static native int FT4222_I2CMaster_Init(FT4222Library.FT_HANDLE ftHandle, int kbps);
FT_HANDLE 在哪里(由 JNAerator 自动生成):
public static class FT_HANDLE extends PointerType {
public FT_HANDLE(Pointer address) {
super(address);
}
public FT_HANDLE() {
super();
}
};
C 代码在 Mac 上正常工作(返回 0):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ftd2xx.h"
#include "libft4222.h"
static void init()
{
FT_HANDLE ftHandle = (FT_HANDLE)NULL;
FT_OpenEx("FT4222 A", FT_OPEN_BY_DESCRIPTION, &ftHandle);
printf("Init %d",FT4222_I2CMaster_Init(ftHandle,100));
}
不同平台上的不同结果往往是类型映射的一种情况,但这里没有明显的区别。 我将指出我在代码中看到的一些不一致之处,希望您可以使用这些信息进一步排除故障。
图书馆返回类型FT_OpenEx()
是FT_STATUS
,并返回类型FT4222_I2CMaster_Init()
是FT4222_STATUS
,这进一步证明作为的延伸FT_STATUS
......而事实上它们使用相同的枚举整数值的基础,但目前还不清楚如何它们被进一步定义。 从逻辑上讲,人们期望两者具有相同的数据类型,但是在您的映射中, FT_STATUS
映射到NativeLong
并且FT4222_STATUS
映射到int
。
在头文件中, FT_STATUS
基于 Windows API 被 typedef 为ULONG
。 这在 Windows 上是 4 个字节,但在 macOS 上可能是 8 个字节,这表明NativeLong
映射可能是正确的。 但是ULONG
不是 macOS 上的标准类型,所以我不确定它应该是什么......也许检测 C 代码以获得该类型的大小会很有用。 此外,鉴于本native
( 直接映射)声明,我怀疑原始int
返回类型可能有问题。
可能相关, FT4222_STATUS
代码只是 C 中的enum
类型,因此标准不保证宽度。 如果FT4222_STATUS
的返回类型在 macOS 上很short
,我不会感到惊讶。
我不确定为什么返回类型会有所作为(没有堆栈损坏),但开始查看是一回事。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.