Creating a JNA Structure from a Pointer

2,306 views
Skip to first unread message

Thibaut DIRLIK

unread,
Sep 7, 2015, 8:39:10 AM9/7/15
to Java Native Access
Hello,

I have a pointer, returned by a native call which points to a C structure. I mapped this structure in JNA.

The pointer is returned by native code, the structure is NOT allocated on Java side.

Then I do the following to convert my Pointer to a structure instance:

handle = (WLINK_HANDLE) Structure.newInstance(WLINK_HANDLE.class, myPointer);

With WLINK_HANDLE being my JNA structure.

It seems that it works fine. Then, later, I want to change some field of this structure:

handle.instruction = (byte)0x07;
handle
.write();

And this does not work as exapected. I debugged in the write() method and I see that it writes value of "0" instead "0x07" to me field, I don't know why.

Maybe I missed something ?

Thanks,

Thibaut



Timothy Wall

unread,
Sep 7, 2015, 9:06:45 AM9/7/15
to jna-...@googlegroups.com
Most Structure implementations should include a Pointer-based constructor, e.g.

public class MyStructure extends Structure {
public MyStructure(Pointer p) {
super(p);
read();
}
}

This avoids any extraneous memory allocation by JNA. Don’t use Structure.newInstance().

As for why “write()” doesn’t work, that would happen if you declared the field “volatile”. However, JNA takes care of automatically calling “write()” and “read()” during a native function call; it’s not clear why you’d need to call it explicitly.

Care to include your actual definition?
> --
> You received this message because you are subscribed to the Google Groups "Java Native Access" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to jna-users+...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Thibaut DIRLIK

unread,
Sep 7, 2015, 10:22:31 AM9/7/15
to Java Native Access
Hi,

Thanks for your answer, I tried to subclass like you said but I got this exception when calling read():

Pointer native@0xdf0150 already mapped to com.alcineo.protocols.ProtocolWlink$2@13ead767

Here is my definition of Structure:

public static class WLINK_HANDLE extends Structure {
 
public static interface SendFunc extends Callback {
 
int invoke(WLINK_HANDLE handle, Pointer data, int nbytes);
 
}
 
public static interface ReceiveFunc extends Callback {
 
int invoke(WLINK_HANDLE handle, Pointer outData, IntByReference nbytes, NativeLong timeoutms);
 
}
 
public static interface FlushFunc extends Callback {
 
int invoke(WLINK_HANDLE handle);
 
}
 
public WLINK_HANDLE(Pointer p) {
 
super(p);
  read
();
 
}
 
public byte seq_nb; /**< Sequence number */
 
public byte sender_id_const;
 
public byte sender_id; /**< Sender index */
 
public byte receiver_id_const;
 
public byte receiver_id; /**< Receiver index */
 
public byte instruction; /**< Instruction identifier */
 
public short len; /**< Len */
 
public NativeLong timeoutms;
 
public int channel;
 
public Pointer handle;
 
public SendFunc send;
 
public ReceiveFunc receive;
 
public FlushFunc flush;
 
public Pointer listener_list;
 
@Override
 
protected List getFieldOrder() {
 
return Arrays.asList("seq_nb", "sender_id_const", "sender_id", "receiver_id_const",
   
"receiver_id", "instruction", "len", "timeoutms", "channel", "handle",
   
"send", "receive", "flush", "listener_list");
 
}
}


And the way I instantiate it:

handle = new WLINK_HANDLE(handleRef.getValue());


Thanks for your help !

Timothy Wall

unread,
Sep 7, 2015, 10:57:29 AM9/7/15
to jna-...@googlegroups.com
Unless you actually need to invoke or set the callbacks, you should leave them as Pointer.

JNA will not allow you to map the same pointer value to different callback types (which sometimes happens when the C library maps a generic no-op default function pointer to a number of different callbacks).

Thibaut DIRLIK

unread,
Sep 7, 2015, 11:15:36 AM9/7/15
to Java Native Access
Ok I reverted them as Pointer for now to help debugging. I checked the content of my structure just after the construction, and it's null-initialized, all fields are 0/null, which should not be the case because the specified pointer contains non-null memory (I checked on C side). I also check that I pointer address I use is correct, and it is.

So I don't know why, but after calling:

handle = new WLINK_HANDLE(handleRef.getValue());

My handle is an empty structure.

Thibaut DIRLIK

unread,
Sep 7, 2015, 11:18:26 AM9/7/15
to Java Native Access
Ok, calling read() AFTER the construction (not in the constructor, because it throws an exception) make it work !

Timothy Wall

unread,
Sep 7, 2015, 11:47:20 AM9/7/15
to jna-...@googlegroups.com
What exception are you seeing when calling Structure.read() from the constructor?

Usually the only issue there is when some field depends on another (like a primitive array length).

Thibaut DIRLIK

unread,
Sep 7, 2015, 4:54:14 PM9/7/15
to jna-...@googlegroups.com

Pointer native@0xdf0150 already mapped to com.alcineo.protocols.ProtocolWlink$2@13ead767

This one.

You received this message because you are subscribed to a topic in the Google Groups "Java Native Access" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/jna-users/Uft6T4zsLu8/unsubscribe.
To unsubscribe from this group and all its topics, send an email to jna-users+...@googlegroups.com.

Timothy Wall

unread,
Sep 7, 2015, 5:19:40 PM9/7/15
to jna-...@googlegroups.com
If you dump the Structure’s native memory, is the same pointer value used for multiple callback fields?

Thibaut DIRLIK

unread,
Sep 8, 2015, 2:46:44 AM9/8/15
to jna-...@googlegroups.com
Hum it works now. Maybe I tried with something different. Anyway thanks for your help, everything works now !
Reply all
Reply to author
Forward
0 new messages