0

我正在尝试将此函数转换为 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为or CredUIPromptForWindowsCredentialsWPointerPointerByReference

函数CredUIPromptForWindowsCredentialsW返回代码 160(“错误参数)。怎么了?

4

1 回答 1

0

因为 Java 在“按值”和“按引用”之间没有区别,所以 JNAStructure根据最常见的使用模式推断它应该用于给定用法。

在这种情况下,本机PCREDUI_INFO表示struct*,这是结构作为函数参数的更常见用法。JNA 将默认使用您分配的内存地址作为本机参数,并在本机调用前后Structure自动将 的 Java 字段与本机内存同步。Structure

如果您通过Structure.getPointer(),则不会执行同步,并且您的本机代码将获得一块内容未定义的内存(因此您的“错误参数”错误)。

于 2016-04-21T12:23:43.463 回答