【问题标题】:Java JNA UCHAR and PUCHARJava JNA UCHAR 和 PUCHAR
【发布时间】:2012-01-12 14:04:18
【问题描述】:

我正在寻找“WlanHostedNetworkSetSecondaryKey”和“WlanHostedNetworkSetProperty”的 Java 字符串。一个人想要一个带有 CHAR[] 的结构中的结构,而第一个想要一个 PUCHAR。我尝试使用 String、char[]、byte[] 和 Memory,但它们会继续产生相同的错误(首先是错误的参数或错误的配置文件)。任何方式都可以使用 JNA 进行更多调试(可能不是:()? 我也无法在任何地方阅读所使用的字符编码,除了它不是 ANSI 之外。任何帮助都会很棒!

        * DWORD WINAPI WlanHostedNetworkSetSecondaryKey(
        __in        HANDLE hClientHandle,
        __in        DWORD dwKeyLength,
        __in        PUCHAR pucKeyData,
        __in        BOOL bIsPassPhrase,
        __in        BOOL bPersistent,
        __out_opt   PWLAN_HOSTED_NETWORK_REASON pFailReason,
        __reserved  PVOID pvReserved


     * DWORD WINAPI WlanHostedNetworkSetProperty(
        __in        HANDLE hClientHandle,
        __in        WLAN_HOSTED_NETWORK_OPCODE OpCode,
        __in        DWORD dwDataSize,
        __in        PVOID pvData,
        __out_opt   PWLAN_HOSTED_NETWORK_REASON pFailReason,
        __reserved  PVOID pvReserved
        );

关于这方面的大多数文档

http://msdn.microsoft.com/en-us/library/dd439496(v=VS.85).aspx

http://jna.java.net/javadoc/overview-summary.html#pointers

http://en.wikipedia.org/wiki/Java_Native_Access

以下评论:

   String buffer = "test";
   ByteBuffer buf = ByteBuffer.allocateDirect(buffer.length()); buf.put(buffer.getBytes()); 
   Pointer pucKeyData = Native.getDirectBufferPointer(buf);

   System.out.println(
           CLibrary.INSTANCE.WlanHostedNetworkSetSecondaryKey(handle.getValue(), 5, pucKeyData, 0, 0, reason, reserved));

【问题讨论】:

  • PUCHAR 被定义为一个 C 宏 POINTER(u_byte),它是一个 C 指针,unsigned byte * 指向一个无符号字节数组。但是,如果您在 JNA 结构中使用 byte[]char[],JNA 会抱怨,Array fields must be initialized 用于 byte[]char[] 字段。在您的情况下,它违背了让dwKeyLength 定义动态无符号字节数组pucKeyData 的大小的目的。 pucKeyData 的正确类型是Pointer。但是,您需要找到一种方法,根据pucKeyData 给出的大小为pucKeyData 的这个Pointer 字段分配一个数组。
  • 我尝试了 Memory.setString 和 Memory.getPointer,但它会使 JVM 崩溃。
  • Memory.getPointer 显然是不必要的,因为 Memory 已经是一个指针。修复了崩溃,但仍然导致参数错误
  • 你需要用Pointer来代表PUCHAR。要将直接缓冲区分配给 pucKeyData 的指针,您需要执行以下操作:ByteBuffer buf = ByteBuffer.allocateDirect(dwKeyLengthSize); buf.put(buffer.getBytes()); pucKeyData = Native.getDirectBufferPointer(buf);
  • 我做了相应的尝试,但仍然得到错误的参数结果。 (返回 87,原因 2)..

标签: java c winapi jna


【解决方案1】:

我正在重新表述我迄今为止发表的评论(加上一些更正):

UCHAR 定义为 C 宏 u_byte,即 unsigned byte。但是,在 Java 中,我们没有 unsigned byte 类型,只有来自 byte 类型的有符号字节。别担心,要在 Java 中获得 unsigned byte,我们使用这个技巧:((int)mybyte & 0xFF)

PUCHAR 被定义为一个 C 宏 POINTER(u_byte),它是一个 C 指针,unsigned byte * 指向一个无符号字节数组。原因是要有一个动态数组。

但是,如果您在 JNA Structure 中使用 byte[]char[],JNA 会抱怨,Array fields must be initialized 用于 未初始化 byte[]char[] 字段。在您的情况下,它违背了使用dwKeyLength 字段来定义动态无符号字节数组pucKeyData 的大小的目的。

pucKeyData 的正确 JNA 类型是 Pointer。但是,您需要找到一种方法,根据 WlanHostedNetworkSetSecondaryKey 结构中 dwKeyLength 长度给出的大小,为 pucKeyData 字段的 Pointer 字段分配一个数组。

要将初始化的无符号字节数组分配给Pointer,我们需要直接使用ByteBuffer。请记住在使用后手动释放此直接缓冲区,因为它不再由 Java GC 管理...

String buffer = "1234567890";
DWORD dwKeyLength = new DWORD(buffer.length());
ByteBuffer buf = ByteBuffer.allocateDirect(dwKeyLength.intValue()); 
buf.put(buffer.getBytes()); 
Pointer pucKeyData = Native.getDirectBufferPointer(buf);

System.out.println("pucKeyData data:" + pucKeyData.getString(0));

buf = null;
pucKeyData = null;

如果您从 JNA 异常中得到错误的参数,则意味着您的 JNA 方法的一个或多个参数使用了不正确的数据类型。

JNA 提供了一些 WinDef 类类型,例如 DWORD。但不包括一些 WinDef 类型,如 PUCHAR。但是,要将整数值分配给 DWORD 类型并将其取回,您需要这样做:

DWORD dwKeyLength = new DWORD(5);
System.out.println("dwKeyLength integer value: " + dwKeyLength.intValue());

注意:本文基于 JNA 平台版本 3.3.0

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-10
    相关资源
    最近更新 更多