首页 > 解决方案 > NativeLongByReference 在 x64 操作系统上仅包含 32 位数字

问题描述

typedef unsigned __int64 EntityNumber;关于输入参数,我对函数有一个严重的问题。

库是 x64,操作系统是 Windows 10。

如果我通过NativeLongByReference,输出缓冲区只有 4 个字节,所以如果超过 32 位,我的数字就会损坏。我用转储检查了它,它确实包含一半的 64 位Long

如果我通过DoubleByReference,我可以用doubleByReference.pointer.getLong(0).

虽然这个 hack 有效,但我想知道,如果两个操作系统都是 64 位, Long有什么问题?

long TRANS2QUIK_API __stdcall TRANS2QUIK_SEND_SYNC_TRANSACTION (LPSTR lpstTransactionString, long* pnReplyCode, PDWORD pdwTransId, EntityNumber* pnOrderNum, LPSTR lpstrResultMessage, DWORD dwResultMessageSize, long* pnExtendedErrorCode, LPSTR lpstErrorMessage, DWORD dwErrorMessageSize);

和 JNA 接口

    NativeLong TRANS2QUIK_SEND_SYNC_TRANSACTION(
            String lpstTransactionString,
            NativeLongByReference pnReplyCode,
            NativeLongByReference pdwTransId,
            DoubleByReference pdOrderNum, <- hack!
            byte[] lpstrResultMessage,
            int dwResultMessageSize,
            NativeLongByReference pnExtendedErrorCode,
            byte[] lpstrErrorMessage,
            int dwErrorMessageSize
    );

openjdk version "11.0.4" 2019-07-16
OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.4+11)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 11.0.4+11, mixed mode)

标签: javajna

解决方案


在 Windows 上,along是一个 32 位整数,与操作系统位数无关。

因此在 WindowsNativeLong上将指向一个 32 位的long值,而不必在 Windows 代码中使用。该NativeLong类型更适用于 *nix 操作系统。

您可以在 JNA 源代码中看到这一点,其中 a 的大小在Native.javaNativeLong中定义,其中派生自类型的本机函数,一个 32 位整数LONG_SIZEsizeof()long

在 Windows 上改变大小的类型是Pointer类型。实际上,指向 的指针NativeLongByReference在各个系统上是 32/64 位,而指向的值是 32 位。

在您的情况下,您的变量被明确定义为 64 位整数,因此LongByReference正确的映射也是如此。


推荐阅读