Consider a header file defining this method:
<code>ErrorCode_t GetBlob(Handle_const_t hHandle, uint8_t* const pValue, size_t* const pnSize);
</code>
<code>ErrorCode_t GetBlob(Handle_const_t hHandle, uint8_t* const pValue, size_t* const pnSize);
</code>
ErrorCode_t GetBlob(Handle_const_t hHandle, uint8_t* const pValue, size_t* const pnSize);
This method writes n
bytes into the array starting at the pointer of pValue
. The size n
will be set at the pointer of pnSize
.
The header can be converted into Java source code using jextract, which gives:
<code>public static long GetBlob(MemorySegment hHandle, MemorySegment pValue, MemorySegment pnSize) {
// ..
}
</code>
<code>public static long GetBlob(MemorySegment hHandle, MemorySegment pValue, MemorySegment pnSize) {
// ..
}
</code>
public static long GetBlob(MemorySegment hHandle, MemorySegment pValue, MemorySegment pnSize) {
// ..
}
After reading /questions/76978598 and /questions/71250218 I allocated a C_POINTER
with unbounded address layout and called the method:
<code> MemorySegment handle = ..;
MemorySegment arrayPointer = Arena.global().allocate(C_POINTER);
MemorySegment sizePointer = Arena.global().allocate(JAVA_LONG);
Accessor_h.GetBlob(handle, arrayPointer, sizePointer);
</code>
<code> MemorySegment handle = ..;
MemorySegment arrayPointer = Arena.global().allocate(C_POINTER);
MemorySegment sizePointer = Arena.global().allocate(JAVA_LONG);
Accessor_h.GetBlob(handle, arrayPointer, sizePointer);
</code>
MemorySegment handle = ..;
MemorySegment arrayPointer = Arena.global().allocate(C_POINTER);
MemorySegment sizePointer = Arena.global().allocate(JAVA_LONG);
Accessor_h.GetBlob(handle, arrayPointer, sizePointer);
The call is successful. The sizePointer
contains the size of the array.
But reading the array data fails. I tried the following:
<code> arrayPointer.get(C_POINTER, 0L)
.toArray(JAVA_BYTE); // fails with "Segment is too large to wrap as byte[]. Size: 9223372036854775807"
</code>
<code> arrayPointer.get(C_POINTER, 0L)
.toArray(JAVA_BYTE); // fails with "Segment is too large to wrap as byte[]. Size: 9223372036854775807"
</code>
arrayPointer.get(C_POINTER, 0L)
.toArray(JAVA_BYTE); // fails with "Segment is too large to wrap as byte[]. Size: 9223372036854775807"
Or:
<code> arrayPointer.get(C_POINTER, 0L)
.asSlice(0L, sizePointer.get(JAVA_LONG, 0L))
.toArray(JAVA_BYTE); // SIGSEGV (0xb)
</code>
<code> arrayPointer.get(C_POINTER, 0L)
.asSlice(0L, sizePointer.get(JAVA_LONG, 0L))
.toArray(JAVA_BYTE); // SIGSEGV (0xb)
</code>
arrayPointer.get(C_POINTER, 0L)
.asSlice(0L, sizePointer.get(JAVA_LONG, 0L))
.toArray(JAVA_BYTE); // SIGSEGV (0xb)
Or:
<code> arrayPointer
.toArray(JAVA_BYTE); // seems to contain the correct data, but only the first eight bytes
</code>
<code> arrayPointer
.toArray(JAVA_BYTE); // seems to contain the correct data, but only the first eight bytes
</code>
arrayPointer
.toArray(JAVA_BYTE); // seems to contain the correct data, but only the first eight bytes
Or:
<code> arrayPointer
.asSlice(0L, sizePointer.get(JAVA_LONG, 0L))
.toArray(JAVA_BYTE); // fails with "java.lang.IndexOutOfBoundsException: Out of bound access on segment MemorySegment"
</code>
<code> arrayPointer
.asSlice(0L, sizePointer.get(JAVA_LONG, 0L))
.toArray(JAVA_BYTE); // fails with "java.lang.IndexOutOfBoundsException: Out of bound access on segment MemorySegment"
</code>
arrayPointer
.asSlice(0L, sizePointer.get(JAVA_LONG, 0L))
.toArray(JAVA_BYTE); // fails with "java.lang.IndexOutOfBoundsException: Out of bound access on segment MemorySegment"
What can I do, to safely read the byte array in Java?