简体   繁体   English

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

[英]JNA throws java.lang.UnsatisfiedLinkError for a Windows API function in the correct DLL with the correct name

JNA is throwing: JNA抛出:

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

for a mapping where I've verified that DsMakeSpn exists in ntdsapi.dll according to MSDN and I'm on Windows Server 2008, so the function is available. 根据MSDN ,我已经验证了DsMakeSpn存在ntdsapi.dll并且我在Windows Server 2008上,因此该功能可用。 JNA loads ntdsapi.dll without error. JNA加载ntdsapi.dll不会出现错误。

I've extended StdCallLibrary since it's a WINAPI function; 我扩展了StdCallLibrary因为它是WINAPI函数。 it isn't a linkage issue. 这不是链接问题。

This makes very little sense. 这毫无意义。

The code with javadoc trimmed for brevity: 为简洁起见,修剪了带有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;

}

The issue is that ntdsapi.dll actually exposes two variants of DsMakeSpn , as shown by Dependency Walker : 问题是ntdsapi.dll实际上公开了DsMakeSpn两个变体,如Dependency Walker所示:

依赖项沃克的屏幕截图

There's an ANSI and a Wide (unicode) variant. 有一个ANSI和一个Wide(unicode)变体。

MSVC will resolve these automatically. MSVC将自动解决这些问题。 JNA won't. JNA不会。 So you need to explicitly declare your mapping, declaring DsMakeSpnW and using WString seg: 因此,您需要显式声明您的映射,声明DsMakeSpnW并使用WString seg:

    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;

Note the change of buffer from byte[] to char[] for unicode calls. 请注意,对于unicode调用,缓冲区从byte[]更改为char[]

See https://github.com/twall/jna/issues/377 for issue report. 有关问题报告,请参见https://github.com/twall/jna/issues/377

If you want to expose both variants you can use the W32APIFunctionMapper . 如果要公开这两种变体,则可以使用W32APIFunctionMapper

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM