JNA Java CredUIPromptForWindowsCredentialsW
Я пытаюсь преобразовать эту функцию в JNA:
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.mycode.winapi;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.NativeLong;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.WString;
import com.sun.jna.platform.win32.Sspi;
import com.sun.jna.platform.win32.WinDef.HBITMAP;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinDef.ULONG;
import com.sun.jna.platform.win32.WinDef.ULONGByReference;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.PointerByReference;
import java.util.Arrays;
import java.util.List;
/**
* Credui
* @author
*/
public interface Credui extends Library {
/**
* INSTANCE
*/
Credui INSTANCE = (Credui) Native.loadLibrary("Credui", Credui.class);
/**
* CredUIPromptForWindowsCredentialsW
* DWORD WINAPI CredUIPromptForWindowsCredentials(
* _In_opt_ PCREDUI_INFO pUiInfo,
* _In_ DWORD dwAuthError,
* _Inout_ ULONG *pulAuthPackage,
* _In_opt_ LPCVOID pvInAuthBuffer,
* _In_ ULONG ulInAuthBufferSize,
* _Out_ LPVOID *ppvOutAuthBuffer,
* _Out_ ULONG *pulOutAuthBufferSize,
* _Inout_opt_ BOOL *pfSave,
* _In_ DWORD dwFlags
* );
*
* @return
*/
int CredUIPromptForWindowsCredentialsW(
PointerByReference pUiInfo,
int dwAuthError,
ULONGByReference pulAuthPackage,
Pointer pvInAuthBuffer,
ULONG ulInAuthBufferSize,
PointerByReference ppvOutAuthBuffer,
ULONGByReference pulOutAuthBufferSize,
IntByReference pfSave,
int dwFlags
);
/**
* CREDUI_INFO
*
* typedef struct _CREDUI_INFO {
* DWORD cbSize;
* HWND hwndParent;
* PCTSTR pszMessageText;
* PCTSTR pszCaptionText;
* HBITMAP hbmBanner;
* } CREDUI_INFO, *PCREDUI_INFO;
*/
public static class CREDUI_INFO extends Structure {
public int cbSize;
public HWND hwndParent;
public WString pszMessageText;
public WString pszCaptionText;
public HBITMAP hbmBanner;
/**
* getFieldOrder
* @return
*/
@Override
protected List getFieldOrder() {
return Arrays.asList(new String[]{
"cbSize",
"hwndParent",
"pszMessageText",
"pszCaptionText",
"hbmBanner",
});
}
}
}
И звоните:
Credui.CREDUI_INFO info = new Credui.CREDUI_INFO();
info.cbSize = info.size();
info.pszCaptionText = new WString(caption);
info.pszMessageText = new WString(message);
PointerByReference pinfo = new PointerByReference(info.getPointer());
WinDef.ULONGByReference authPackage = new WinDef.ULONGByReference();
PointerByReference outCredBuffer = new PointerByReference();
WinDef.ULONGByReference outCredSize = new WinDef.ULONGByReference();
IntByReference save = new IntByReference(0);
WinDef.ULONG ulInAuthBufferSize = new WinDef.ULONG(0);
int result = Credui.INSTANCE.CredUIPromptForWindowsCredentialsW(pinfo, 0, authPackage,
null, ulInAuthBufferSize, outCredBuffer, outCredSize, save, 0);
if( result == 0 ) {
}
Я пытался объявить pUiInfo
в CredUIPromptForWindowsCredentialsW
как Pointer
или же PointerByReference
,
функция CredUIPromptForWindowsCredentialsW
возвращает код 160 ("неверный параметр"). Что не так?
1 ответ
Поскольку в Java нет различия между "по значению" и "по ссылке", JNA делает вывод, что следует использовать для данного Structure
использование на основе наиболее распространенных моделей использования.
В этом случае родной PCREDUI_INFO
средства struct*
, что является более распространенным использованием структур в качестве параметров функции. JNA по умолчанию будет использовать адрес вашего Structure
выделяется память в качестве собственного аргумента и автоматически синхронизирует Structure
Поля Java с собственной памятью до и после собственного вызова.
Если вы только проходите Structure.getPointer()
, тогда никакая синхронизация не будет выполнена, и ваш нативный код получит блок памяти с неопределенным содержимым (таким образом, ваша ошибка "неверный параметр").