【问题标题】:FTDI library platform differences between Mac and Windows when using JNA使用 JNA 时 Mac 和 Windows 之间的 FTDI 库平台差异
【发布时间】:2020-03-23 16:43:46
【问题描述】:

我目前正在开发一个 Java 应用程序,该应用程序使用 JNA 访问一些 FTDI 库,包括 D2XX 和 LibFT4222。我已经使用 JNAerator 创建了使用的 JNA。这一切都在 Windows 平台上正常工作。但是,当尝试在 Mac 上运行该软件时,我遇到了 LibFT4222 的问题。

FT_OpenEx 在 D2XX 中似乎工作正常,导致没有错误代码,我也可以查看它返回的描述,看到它列为“FT4222 A”。我还能够执行其他功能而不会返回意外的错误代码(例如关闭它两次,第一次导致没有错误代码,第二次导致预期的错误代码)。但是,当尝试在 D2XX 创建的句柄上使用 LibFT4222 进行任何操作时,例如 FT4222_I2CMaster_Init、FT4222_GetVersion 或 FT4222_GetClock,它会产生错误代码 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));
}

【问题讨论】:

  • 如果您可以发布失败的 Mac 代码的一部分,以及产生所需输出的正在工作的 C 文件,这将非常有用。
  • 不确定为什么 FT_HANDLE 是 PointerByReference 而不仅仅是普通的 Pointer 或您定义的扩展 PointerType 的类。同样,如果没有任何源代码显示给您带来问题的映射,就不可能提供更多洞察力。
  • 感谢丹尼尔,编辑了问题以包含一些源代码
  • 差异似乎指向类型不匹配,但我看不到任何明显的东西。一种好奇心是FT_STATUS 返回类型,它被定义为 ULONG。这在 Windows 上绝对是 32 位(int),但在 MacOS 上没有定义。不过,这只会影响返回类型,所以我怀疑这是问题所在。

标签: java jna ftdi jnaerator


【解决方案1】:

不同平台上的不同结果往往是类型映射的情况,但这里并没有明显的区别。我将指出我在代码中看到的一些不一致之处,希望您可以使用这些信息进一步排除故障。

FT_OpenEx() 的库返回类型为FT_STATUSFT4222_I2CMaster_Init() 的返回类型为FT4222_STATUS,进一步记录为FT_STATUS 的扩展...实际上它们使用相同枚举整数值基础,但不清楚它们是如何进一步定义的。从逻辑上讲,人们会期望两者具有相同的数据类型,但是在您的映射中,FT_STATUS 映射到 NativeLongFT4222_STATUS 映射到 int

在头文件中,FT_STATUS 基于 Windows API 被类型定义为 ULONG。这在 Windows 上是 4 个字节,但在 macOS 上可能是 8 个字节,这表明 NativeLong 映射可能是正确的。但是ULONG 不是 macOS 上的标准类型,所以我不确定它应该是什么......也许检测 C 代码以获得该类型的大小会很有用。此外,鉴于 native (Direct Mapping) 声明,我怀疑原始 int 返回类型可能有问题。

可能相关,FT4222_STATUS 代码只是 C 中的enum 类型,因此标准不保证宽度。如果FT4222_STATUS 的返回类型在 macOS 上是 short,我不会感到惊讶。

我不确定为什么返回类型会有所不同(没有堆栈损坏),但这是一回事。

【讨论】:

  • 感谢丹尼尔,我试过了,但似乎没有任何区别。你仍然认为这可能相关吗?从我可以看到 FT_OpenEx 工作正常,因为我可以毫无问题地在手柄上执行 D2XX 功能。只是 FT4222 的功能不起作用。
  • 我后来意识到 setString 确实包含 null,所以这实际上可能是一个错误的答案...我会修复它...你是如何定义 FT_OPEN_BY_DESCRIPTION 的?
  • 我已经完全编辑了我的答案,并提供了另一个解决问题的方向。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-12-03
  • 1970-01-01
  • 1970-01-01
  • 2019-04-23
  • 2018-11-22
  • 2020-03-17
  • 2010-10-29
相关资源
最近更新 更多