JNA使用正确的名称在正确的DLL中为Windows API函数抛出java.lang.UnsatisfiedLinkError

时间:2014-10-30 03:18:48

标签: java windows jna

JNA投掷:

java.lang.UnsatisfiedLinkError: Error looking up function 'DsMakeSpn': The specified procedure could not be found

我已经在Windows Server 2008上验证了DsMakeSpn exists in ntdsapi.dll according to MSDN和我的映射,因此该功能可用。 JNA加载ntdsapi.dll没有错误。

我已延长StdCallLibrary,因为它是WINAPI功能;它不是一个联系问题。

这没什么意义。

为简洁起见修剪了javadoc的代码:

import com.sun.jna.LastErrorException;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Platform;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.PointerByReference;
import com.sun.jna.win32.StdCallLibrary;

interface NTDSAPI extends StdCallLibrary {

    NTDSAPI instance = (NTDSAPI)
            Native.loadLibrary("NTDSAPI", NTDSAPI.class);

    int DsMakeSpn(
            String serviceClass, /* in */
            String serviceName, /* in */
            String instanceName, /* in, optional, may be null */
            short instancePort, /* in */
            String referrer, /* in, optional, may be null */
            IntByReference spnLength, /* in: length of buffer spn; out: chars written */
            byte[] spn /* out string */
            )
        throws LastErrorException;

    public final int 
        ERROR_SUCCESS = 0,
        ERROR_INVALID_PARAMETER = 87,
        ERROR_BUFFER_OVERFLOW = 111;

}

1 个答案:

答案 0 :(得分:1)

问题是,ntdsapi.dll实际上公开了DsMakeSpn的两个变体,如Dependency Walker所示:

screenshot from dependency walker

有ANSI和宽(unicode)变体。

MSVC将自动解决这些问题。 JNA不会。因此,您需要明确声明您的映射,声明DsMakeSpnW并使用WString s。 e.g:

    int DsMakeSpnW(
            WString serviceClass, /* in */
            WString serviceName, /* in */
            WString instanceName, /* in, optional, may be null */
            short instancePort, /* in */
            WString referrer, /* in, optional, may be null */
            IntByReference spnLength, /* in: length of buffer spn; out: chars written */
            char[] spn /* out string */
            )
        throws LastErrorException;

请注意,对于unicode调用,缓冲区从byte[]更改为char[]

有关问题报告,请参阅https://github.com/twall/jna/issues/377

如果您想公开这两种变体,可以使用W32APIFunctionMapper