Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GetDirectBufferAddress: Address out by 4

I am attempting to pass a bytebuffer from Java to native code in android. However i am consistantly getting the returned memory address starting at index 4.

I have tested across various devices and the array is the same size across Java and JNI when calling GetDirectBufferCapacity.

Why is this offset occuring?

Java:

inputBuffer = ByteBuffer.allocateDirect(inputBufferSize);

JNI:

uint8_t* inputBuffer = (uint8_t*) env->GetDirectBufferAddress(inputByteBuffer);

The given memory address is offset by 4 bytes and only by moving the pointer does the array match (as shown below).

uint8_t* inputBuffer = (uint8_t*) env->GetDirectBufferAddress(inputByteBuffer) - 4;
like image 582
Riverchimp Avatar asked Nov 02 '25 08:11

Riverchimp


1 Answers

The address returned is the effective address, based upon the alignment of the buffer. The code (Copyright AOSP, all rights reserved) looks like this:

public static ByteBuffer allocateDirect(int capacity) {
    if (capacity < 0) {
        throw new IllegalArgumentException("capacity < 0: " + capacity);
    }
    // Ensure alignment by 8.
    MemoryBlock memoryBlock = MemoryBlock.allocate(capacity + 7);
    long address = memoryBlock.toLong();
    long alignedAddress = (address + 7) & ~(long)7;
    return new DirectByteBuffer(memoryBlock, capacity, (int)(alignedAddress - address), false, null);
}

When you get the direct address, you get the effective address, which is aligned, while the actual buffer is not aligned.

like image 188
dagalpin Avatar answered Nov 04 '25 22:11

dagalpin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!