0

I have a strage issue with the function with reference to typedef unsigned __int64 EntityNumber; input parameter.

Library is x64, OS is Windows 10.

If I pass NativeLongByReference, the output buffer has only 4 bytes, so my number is broken if it exceeds 32-bit. I checked it with dump and it indeed contains half of 64-bit Long

If I pass DoubleByReference I can get my Long with doubleByReference.pointer.getLong(0).

While this hack works, I wonder, what's problem with Long if both OSes are 64-bit?

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);

and JNA interface

    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)
abi
  • 99
  • 8

1 Answers1

2

On Windows, a long is a 32-bit integer, regardless of the OS bitness.

Therefore NativeLong will point to a 32-bit long value on Windows, and is not necessary to use in Windows code. The NativeLong type is more applicable to *nix operating systems.

You can see this in the JNA source, where the size of a NativeLong is defined in Native.java where LONG_SIZE derives from the native sizeof() function for the long type, a 32-bit integer.

The type that does change size on Windows is the Pointer type. In fact, the pointer to the NativeLongByReference is 32/64 bit on the respective systems, while the value pointed to is 32 bits.

In your case, your variable is clearly defined as a 64-bit integer, so LongByReference would be the correct mapping.

Daniel Widdis
  • 8,424
  • 13
  • 41
  • 63