Java Объявление Linkedlist JNA - PullRequest
0 голосов
/ 20 июня 2020

Мне нужно получить доступ к .dll с собственным кодом C ++ из приложения Java. собственная функция int работает хорошо, но для Linkedlist Struct я не могу найти никаких ссылок на Inte rnet, как объявить интерфейс java

этот код C ++

struct usb_relay_device_info
{
    unsigned char *serial_number;
    char *device_path;
    usb_relay_device_type type;
    usb_relay_device_info* next;
};

int EXPORT_API usb_relay_init(void);
struct usb_relay_device_info EXPORT_API * usb_relay_device_enumerate(void);
int EXPORT_API  usb_relay_device_open(struct usb_relay_device_info* device_info);

Это java часть

public interface JNI extends Library {
JNI INSTANCE = (JNI) Native.loadLibrary("usb", JNI.class);

public static class usb_relay_device_info extends Structure {
    public static class DeviceInfo extends usb_relay_device_info implements Structure.ByValue {
    }

    public byte[] serial_number = new byte[1024];
    public String device_path;
    public int type;
}


int usb_relay_init();
usb_relay_device_info.DeviceInfo usb_relay_device_enumerate();
int usb_relay_device_open(usb_relay_device_info.DeviceInfo deviceInfo);

}

Я уже создал только структуру в коде java (НЕ Linkedlist Struct). Поэтому, когда я вызываю функцию, значения не отображаются, потому что это должен быть список (связанный список в C ++)

1 Ответ

1 голос
/ 22 июня 2020

Вы говорите: «Я не могу найти ссылку на Inte rnet, как объявить интерфейс java», но есть множество ссылок, включая Обзор JNA, связанных с главной страницей проекта.

Здесь вы обнаружите, что char * является строкой C и должна быть сопоставлена ​​с Java s String.

Сопоставление usb_relay_device_type должно быть указано в API, который вы сопоставляете. В данном случае это тип enum, который является целым числом, поэтому, вероятно, здесь подходит int. (Бывают случаи, когда это может быть меньшее целое число, например short или byte, но это редко.)

Что касается указателя на следующее устройство, оно также упоминается на странице обзора в разделе struct*. Ссылка (или явно) ведет на Structure.ByReference. Это может быть неочевидно, но JNA FAQ , также связанный с главной страницей проекта JNA, расширяется. Если это все еще не ясно, вот краткое изложение:

  • По умолчанию структуры, перечисленные как поля внутри структуры, обрабатываются «по значению», то есть вся структура и ее поля вставляются в строку. Чтобы получить такое поведение, вы можете просто объявить имя структуры.
  • Если вы хотите противоположное поведение (по ссылке), вы должны явно указать это, и JNA отобразит указатель на структуру в другом месте. Это тот случай, который у вас есть, и правильное отображение структуры - usb_relay_device_info.ByReference. (Вам также необходимо изменить объявление структуры для реализации ByReference - пример этого приведен в обзоре JNA, ссылка на который приведена выше.)
  • При использовании в аргументах функции, таких как usb_relay_device_open(), обратное верно: "По ссылке" используется по умолчанию, и вам нужно только явно указать "По значению", если это актуально. В данном случае это не так - собственное объявление включает указатель: (usb_relay_device_info*), поэтому вам нужно поведение ByReference. Вы можете просто указать здесь usb_relay_device_info device_info, и ByReference будет неявным. Или, если вы предпочитаете (это не обязательно), вы можете сделать usb_relay_device_info.ByReference device_info, и это будет просто избыточно.

Таким образом, ваше структурное отображение должно быть:

class usb_relay_device_info extends Structure {
    public static class ByReference extends usb_relay_device_info implements Structure.ByReference { }

    public String serial_number;
    public String device_path;
    public int type;
    public usb_relay_device_info.ByReference next;
};

Вам нужно будет добавить FieldOrder, желательно с аннотацией.

...