Различия в платформе библиотеки FTDI между Ma c и Windows при использовании JNA - PullRequest
0 голосов
/ 23 марта 2020

В настоящее время я работаю над приложением Java, которое использует JNA для доступа к некоторым библиотекам FTDI, как D2XX, так и LibFT4222. Я использовал JNAerator для создания используемого JNA. Это все работает правильно на Windows платформах. Однако при попытке запустить программное обеспечение на Ma c у меня возникает проблема с LibFT4222.

FT_OpenEx В D2XX, похоже, работает правильно, в результате код ошибки отсутствует, я также могу проверить его возвращенное описание, чтобы увидеть его в списке как «FT4222 A». Я также могу выполнять другие функции, не возвращая неожиданный код ошибки (например, дважды закрывая его, первый раз не получая код ошибки, второй - один, как и ожидалось). Однако при попытке выполнить любую операцию с использованием LibFT4222 на дескрипторе, созданном D2XX, например FT4222_I2CMaster_Init, FT4222_GetVersion или FT4222_GetClock, выдается код ошибки 1000 FT4222_DEVICE_NOT_SUPPORTED.

Я попытался поиграться с сгенерированным кодом JNA, таким как изменение типа FT HANDLE с PointerByReference на IntByReference, и могу заставить его работать на Windows корректно, как и раньше, но все же, похоже, ничто не заставляет его работать на Ма c.

Те же логи c работают правильно, используя модифицированные версии файлов Sample C, которые предоставляет FTDI (используя тот же LibFT4222.dylib), поэтому я знаю, что он будет работать правильно на Ma c. И как уже упоминалось, все вышеперечисленное работает без проблем на Windows.

Сможет ли кто-нибудь рассказать о различиях между Ma c OSX и Windows, которые могут вызывать такое поведение?

Отредактировано для включения кода, Пример Java кода (В этом случае описание будет «FT4222 A», и OpenEx, кажется, будет работать правильно). Это работает на Windows, но на Ma c 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 Код работает правильно для Ma c (возвращает 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));
}

1 Ответ

0 голосов
/ 06 апреля 2020

Разные результаты на разных платформах часто являются случаем отображения типов, но здесь нет очевидной разницы. Я укажу на некоторые несоответствия, которые я вижу в коде, в надежде на дальнейшее устранение неполадок, используя эту информацию.

Тип возврата библиотеки FT_OpenEx() равен FT_STATUS, а тип возврата - FT4222_I2CMaster_Init() - это FT4222_STATUS, что также задокументировано как расширение FT_STATUS ... и фактически они используют ту же базу целочисленных значений enum, но неясно, как они определены далее. Логически можно ожидать одинаковых типов данных для обоих, однако в вашем отображении FT_STATUS отображается на NativeLong, а FT4222_STATUS отображается на int.

В заголовочном файле FT_STATUS имеет typedef'd to ULONG на основе Windows API. Это 4 байта в Windows, но может быть 8 байтов в macOS, что говорит о том, что отображение NativeLong, вероятно, правильно. Но ULONG не является стандартным типом в macOS, поэтому я не уверен, каким он должен быть ... возможно, было бы полезно использовать код C для получения размера этого типа. Кроме того, учитывая объявление native ( Direct Mapping ), я подозреваю, что примитивный тип возврата int может быть проблематичным c.

Возможно связаны, коды FT4222_STATUS просто enum введите C, поэтому ширина не гарантируется стандартом. Меня не удивит, если тип возврата для FT4222_STATUS будет short в macOS.

Я не уверен, почему тип возврата будет иметь значение (если не считать повреждение стека), но это одна вещь начать смотреть.

...