2015-07-28 9 views
0

Я вызываю dll с использованием JNA и кода, сгенерированного с использованием Jnaerator. Один из методов требует строки, а подписи JNA принимает ByteBuffer.Использование ByteBuffer для представления строки в вызове JNA приводит к дополнительным символам в буфере

Я попытался выделения ByteBuffer как прямой (ByteBuffer.allocateDirect) и непрямого (ByteBuffer.wrap), но в обоих случаях несколько раз строка, которая достигает DLL имеет дополнительные случайные символы (например, ReceiptÚeœ). Исходный байт [] есть (получение = 52 65 63 65 69 70 74), но также переменное количество дополнительных случайных байтов (01 da 65 9c 19). Случайно строка правильная, без дополнительных байтов.

Я пробовал эквивалентный код, используя BridJ вместо JNA (подпись метода принимает тогда имя указателя), и в этом случае он отлично работает. К сожалению, я не могу переключиться на BridJ, потому что мне нужно использовать классы com.sun.jna.platform.win32, если я не могу произвести замену BridJ для тех, кто (https://stackoverflow.com/questions/31658862/jnaerator-bridj-user32-missing-methods)

Native декларация:

HRESULT extern WINAPI WFSOpen (LPSTR lpszLogicalName, HAPP hApp, LPSTR lpszAppID,DWORD dwTraceLevel, DWORD dwTimeOut, DWORD dwSrvcVersionsRequired, LPWFSVERSION lpSrvcVersion, LPWFSVERSION lpSPIVersion, LPHSERVICE lphService); 

JNAerator ЮНА код:

//works 
@Deprecated 
NativeLong WFSOpen(Pointer lpszLogicalName, Pointer hApp, Pointer lpszAppID, int dwTraceLevel, int dwTimeOut, int dwSrvcVersionsRequired, WFSVERSION lpSrvcVersion, WFSVERSION lpSPIVersion, ShortByReference lphService); 
//does not work 
NativeLong WFSOpen(ByteBuffer lpszLogicalName, Pointer hApp, ByteBuffer lpszAppID, int dwTraceLevel, int dwTimeOut, int dwSrvcVersionsRequired, WFSVERSION lpSrvcVersion, WFSVERSION lpSPIVersion, ShortBuffer lphService); 

Java вызов работает (но не рекомендуется)

Pointer m = new Memory(string.length() + 1); // WARNING: assumes ascii-only string 
m.setString(0, string); 
MsxfsLibrary.INSTANCE.WFSOpen(lpszLogicalName, lphApp.getValue(), lpszAppID, dwTraceLevel, dwTimeOut, dwSrvcVersionsRequired, lpSrvcVersion, lpSPIVersion, lphService); 

Java вызов НЕ работает тест A:

lpszLogicalName = ByteBuffer.wrap(bytes); 
MsxfsLibrary.INSTANCE.WFSOpen(lpszLogicalName, lphApp.getValue(), lpszAppID, dwTraceLevel, dwTimeOut, dwSrvcVersionsRequired, lpSrvcVersion, lpSPIVersion, lphService); 

Java вызов НЕ работает тест B:

byte[] bytes = string.getBytes(); 
return ByteBuffer.wrap(bytes); 
ByteBuffer bb = ByteBuffer.allocateDirect(bytes.length); 
bb.put(bytes); 
lpszLogicalName = bb.position(0); 
msxfsLibrary.WFSOpen(lpszLogicalName, lphApp.getValue(), lpszAppID, dwTraceLevel, dwTimeOut, dwSrvcVersionsRequired, lpSrvcVersion, lpSPIVersion, lphService); 
+0

Ожидающий код? Какова ваша собственная декларация? Каково ваше отображение на Java? Является ли ваш собственный код ожидаемым 'const char *' или 'const wchar_t *'? Обычно JNA отображает 'String' в первый, но это поведение может быть различным в зависимости от того, как вы инициализируете отображение вашей библиотеки. Почему бы просто не сменить подпись, чтобы взять «String», если это то, что ожидает собственный код? – technomage

+0

Уроженец декларация: 'HRESULT ехЬегп WINAPI WFSOpen (LPSTR lpszLogicalName' Jnaerator ЮНА не удается случайным образом, переводит: ' NativeLong WFSOpen (ByteBuffer lpszLogicalName, ... ' Jnaerator Bridj работает отлично, переводится: ' общественного статики длинный WFSOpen (Pointer lpszLogicalName' – movees

+0

Обновите свой вопрос и удалите эти комментарии. – technomage

ответ

0

Если вы имеете в виду _wfsopen(), он ожидает строку широких символов. Либо используйте WString, либо сконфигурируйте свою библиотеку по типу-карте String (см. W32APIOptions.UNICODE_OPTIONS).

+0

Нет, это не визуальная студия wfsopen. Это CEN-XFS, которая принимает LPSTR lpszLogicalName как первый параметр. – movees

0

Я думаю, что происходит то, что вы передаете массив байтов, содержащий вашу строку, но это не строка с нулевым завершением. Вы должны создать массив байтов с дополнительной позицией. Установите эту позицию las в 0 и скопируйте строку в этот массив байтов.

 Смежные вопросы

  • Нет связанных вопросов^_^