2016-04-20 43 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

谢谢你的帮助! –