libimobiledevice возвращает странные символы

Я пытаюсь соединиться с подключенным устройством iOS и получить UDID, используя libimobiledevice и JNA. Вот как я объявил нативные функции:

static native int idevice_new(PointerByReference device, Pointer udid);
static native int lockdownd_client_new(Pointer device, PointerByReference client, String label);
static native int idevice_get_udid(Pointer idevice, StringByReference udid);
static native int lockdownd_query_type(Pointer lockdownd_client, StringByReference type);

Для тестирования я пытаюсь сделать именно то, что запускает команду idevicepair pair делает.

Это мой основной метод:

PointerByReference device = new PointerByReference();
System.out.println("idevice_new error code: " + idevice_new(device, Pointer.NULL));
PointerByReference client = new PointerByReference();
System.out.println("lockdownd_client_new error code: " + lockdownd_client_new(device.getValue(), client, "java"));
StringByReference udid = new StringByReference();
System.out.println("idevice_get_udid error code: " + idevice_get_udid(device.getValue(), udid));
System.out.println("udid: " + udid.getValue());
StringByReference type = new StringByReference();
System.out.println("lockdownd_query_type error code: " + lockdownd_query_type(client.getValue(), type));
System.out.println("lockdownd_query_type: " + type.getValue());
System.out.println("lockdownd_pair error code: " + lockdownd_pair(client.getValue(), Pointer.NULL));

Всякий раз, когда я пытаюсь получить любое строковое значение, он выводит эти странные знаки вопроса:

idevice_new error code: 0
lockdownd_client_new error code: 0
idevice_get_udid error code: 0
udid: ��AZ�
lockdownd_query_type error code: 0
lockdownd_query_type: �HbZ�
lockdownd_pair error code: 0

Персонажи каждый раз разные.

Если вы не можете видеть это:

1 ответ

Решение

UUID меняется каждый раз, потому что он уникален! Каждый новый сгенерированный отличается.

Что касается странных персонажей, ваше отображение uuid (а также type) чтобы StringByReference виновник здесь, так как вы не получаете данные в том формате, в котором они хранятся изначально.

Подпись метода в C (которую вы должны были опубликовать вместе со своим вопросом) отмечает, что тип uuid является **charуказатель на указатель на строку из 8-битных значений C. Копаясь в исходном коде, кажется, что они представляют собой цифры 0-9 и AF в строковом представлении, и либо 32 байта (без дефисов), либо 36 байтов (с) плюс нулевой терминатор. (Обратите внимание, что это не всегда очевидно; они могли бы быть сохранены в 16 байтах как полное значение байта, что API должен фактически задокументировать.)

Внутренне StringByReference класс использует Pointer.getString() метод:

public String getValue() {
    return getPointer().getString(0);
}

Метод getString() только со смещением использует кодировку вашей платформы по умолчанию, которая, вероятно, является многобайтовым набором символов. Это может не совпадать (и, очевидно, не в вашем случае) с 8-битной кодировкой UUID.

Вы должны отобразить UUID как PointerByReference и использовать uuid.getValue().getString(0, "UTF-8") или же uuid.getValue().getString(0, "US-ASCII") чтобы получить строку как 8-битные символы, которые они представляют.

(В качестве альтернативы, вы можете получить байтовый массив и создать из него строку, хотя я не уверен, что вы получите 32- или 36-байтовый результат, так что получайте удовольствие, если вы пойдете по этому пути. можно итерировать смещение и читать побайтово, пока не получите 0. Но я отвлекся.)

Делать то же самое для type поле оставлено в качестве упражнения для читателя.

Другие вопросы по тегам