2016-04-20 68 views
0

我想這個函數轉換JNA:JNA的Java CredUIPromptForWindowsCredentialsW

/* 
* 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) {   
} 

我試圖在CredUIPromptForWindowsCredentialsW申報pUiInfo作爲PointerPointerByReference

功能CredUIPromptForWindowsCredentialsW返回代碼160(「壞參數)。怎麼了?

+0

您的第一個參數需要是'CREDUI_INFO'類型,而不是'PointerByReference'。 – technomage

+0

謝謝!我不明白它爲什麼可以與'CREDUI_INFO'一起工作,並且在文檔中是''PCREDUI_INFO'來聲明。 –

回答

0

因爲Java沒有區別‘的價值’和‘參考’,JNA它應該對給定Structure使用推斷通過最常見的使用模式基於使用。

在這種情況下,本地PCREDUI_INFO意味着struct*,這是結構的函數參數的比較常見的用法。JNA將默認使用您的Structure的分配內存的地址本機參數,並會自動同步Structure的在本地調用之前和之後使用本地內存的Java字段。

如果你只Structure.getPointer(),則沒有同步將被執行,你的本機代碼將獲得與不確定的內容(因此你的「錯誤的參數」的錯誤)內存塊。

+0

謝謝你的幫助! –