RobotRock
RobotRock

Reputation: 4459

Java JNA UCHAR and PUCHAR

I'm looking to get a Java string to 'WlanHostedNetworkSetSecondaryKey' and 'WlanHostedNetworkSetProperty'. One wants a struct within a struct with a CHAR[] and the first one wants a PUCHAR. I tried using String, char[], byte[] and Memory, but they will keep producing me the same errors (Bad parameters or Bad profile something for the first). Any way maybe to debug more with JNA (probably not :()? I also can't read anywhere the characterencoding which is used, except that it's not ANSI.. Any help would be great!

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

For the most documentation on this

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

Following comment:

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

Upvotes: 2

Views: 1748

Answers (1)

ee.
ee.

Reputation: 957

I am rephrasing what I have commented so far (plus some corrections):

UCHAR is defined as a C macro u_byte which is an unsigned byte. But, in Java, we don't have an unsigned byte type, just a signed byte from the byte type. Don't worry, to get an unsigned byte in Java, we use this trick: ((int)mybyte & 0xFF)

PUCHAR is defined as a C macro POINTER(u_byte) which is a C pointer, unsigned byte * that points to an unsigned byte array. The reason is to have a dynamic array.

But, if you use byte[] or char[] in JNA Structure, JNA will complain, Array fields must be initialized for uninitialized byte[] or char[] field. In your case, it defeats the purpose of having dwKeyLength field to define the size of dynamic unsigned byte array pucKeyData.

The right JNA type for the pucKeyData is Pointer. But, you need to find a way to assign an array to this Pointer field for pucKeyData field based on the size given by dwKeyLength length in WlanHostedNetworkSetSecondaryKey structure.

To assign an initialized unsigned byte array to a Pointer, we need to use direct ByteBuffer. Remember to release this direct buffer manually after use since it is no longer managed by 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;

If you get bad parameters from JNA exception, it means one or more parameters of your JNA method are using incorrect data types.

JNA provides a few WinDef class types like DWORD. But a few WinDef types like PUCHAR are not included. But, to assign an integer value to a DWORD type and retrieve it back, you need to do like this:

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

Note: this post is based on JNA platform version 3.3.0

Upvotes: 2

Related Questions