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
поле оставлено в качестве упражнения для читателя.