Mapping a reference to an IntByReference

163 views
Skip to first unread message

Daniel Widdis

unread,
Feb 24, 2016, 6:06:28 PM2/24/16
to Java Native Access
I am attempting to port this code into JNA: https://github.com/Chris911/iStats/blob/master/ext/osx_stats/smc.c

Unfortunately, I'm hitting a wall figuring out how to handle a pointer to a pointer to an int.

Specifically, this variable is defined:

static io_connect_t conn;

The io_connect_t is best mapped by an IntByReference, similar to all the other io_object_t types.  Unfortunately one method is tripping me up.

result = IOServiceOpen(device, mach_task_self(), 0, &conn);

The full declaration of this method is below (note both io_service_t and io_connect_t are the same underying io_object_t, which should be IntByReference.)

kern_return_t IOServiceOpen( io_service_t service, task_port_t owningTask, uint32_t typeio_connect_t *connect );

In this case, the &conn argument is itself an IntByReference, meaning that the .getValue() method, applied to the argument I pass, should match the io_connect_t type itself... basically I want the type of IntByReference.getValue() to also be IntByReference.

In my JNA code, I've represented the argument to the above as IOConnect (extends IOObject, extends IntByReference) but unfortunately I'm stumped trying to use that returned value.  connect.getValue() returns an integer, when that integer is actually still a reference... I need something like connect.getValue().getValue.

I've tried numerous combinations of ints, IntByReferences, and other shenanigans without success.  I'm probably missing something obvious.  Any advice?

Timothy Wall

unread,
Feb 25, 2016, 8:12:55 AM2/25/16
to jna-...@googlegroups.com
Use a PointerByReference to get the “returned” address, and then use Pointer.getInt(0) to dereference it.
> --
> 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.

Daniel Widdis

unread,
Feb 25, 2016, 1:06:16 PM2/25/16
to jna-...@googlegroups.com
Thank you for confirming that at least that portion of what I've tried was the right direction.  However, I'm still unable to get that returned int and/or pointer in subsequent calls to the IntByReference that I'm supposed to correlate with that address.

Here's the relevant block of code:

        IntByReference conn;
        PointerByReference handle = new PointerByReference();

        result = IOKit.INSTANCE.IOServiceOpen(service, SystemB.INSTANCE.mach_task_self(), 0, handle);
        // This returns result == 0, indicating success

        // How do we get handle into conn?
        conn = new IntByReference(handle.getPointer().getInt(0));
        // Have also tried conn.setPointer(handle.getPointer()); with same results 

        result = IOKit.INSTANCE.IOConnectCallStructMethod(conn, IOKit.KERNEL_INDEX_SMC, inputStructure,
                inputStructure.size(), outputStructure, new IntByReference(outputStructure.size()));
        // This fails with result = 0x10000003 (MACH_SEND_INVALID_DEST)
        // This implies conn is uninitialized or already freed


Other relevant information:

- I first tried conn = new IntByReference(handle.getValue().getInt(0)) since it's the (Pointer) value of the PointerByReference that I want.  This resulted in a segfault:
#  SIGSEGV (0xb) at pc=0x000000011aea0094, pid=14022, tid=5891
#
# JRE version: Java(TM) SE Runtime Environment (7.0_67-b01) (build 1.7.0_67-b01)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (24.65-b04 mixed mode bsd-amd64 compressed oops)
# Problematic frame:
# C  [jna1121545115111729308.tmp+0x4094]  Java_com_sun_jna_Native_getInt+0x4

- I tried directly assigning handle.getValue() as the pointer for conn using conn.setPointer(handle.getValue());.  This produced an error 0xe00002bf (kIOReturnIPCError) in the subsequent IOConnectCallStructMethod().

- I have tried many variations on the above including either IntByReference or LongByReference for handle, and using handle.getValue() as the peer to instantiate a Pointer (ignoring Javadoc that says don't do it unless you know what you're doing).   I'm getting either the 0x10000003 or 0xe00002bf (or sometimes a segfault) no matter what I try...

Daniel Widdis

unread,
Feb 25, 2016, 8:00:45 PM2/25/16
to Java Native Access
Well, after digging into the nativeValues of the pointers involved and carefully re-tracing the c headers, it looks like the base type needs to just be a 32-bit integer, so the problematic reference I started this thread with can simply be an IntByReference.

I'm still getting the kIOReturnIPCError most of the time (which is what led me to think I was doing it wrong) but it actually did work once... maybe I'm not releasing a resource somewhere... but I guess this particular question is now resolved.

Unfortunately, I'm hitting a wall figuring out how to handle a pointer to a pointer to an int.

Specifically, this variable is defined:

static io_connect_t conn;

The io_connect_t is best mapped by an IntByReference, similar to all the other io_object_t types.  Unfortunately one method is tripping me up.

  result = IOServiceOpen(device, mach_task_self(), 0, &conn);

The full declaration of this method is below (note both io_service_t and io_connect_t are the same underying io_object_t, which should be IntByReference.)

kern_return_t IOServiceOpen( io_service_t service, task_port_t owningTask, uint32_t type, io_connect_t *connect );

In this case, the &conn argument is itself an IntByReference, meaning that the .getValue() method, applied to the argument I pass, should match the io_connect_t type itself... basically I want the type of IntByReference.getValue() to also be IntByReference.

In my JNA code, I've represented the argument to the above as IOConnect (extends IOObject, extends IntByReference) but unfortunately I'm stumped trying to use that returned value.  connect.getValue() returns an integer, when that integer is actually still a reference... I need something like connect.getValue().getValue.

I've tried numerous combinations of ints, IntByReferences, and other shenanigans without success.  I'm probably missing something obvious.  Any advice?

-- 
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+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

    

Reply all
Reply to author
Forward
0 new messages