Search code examples
javacpointersjna

JNA getting back a byte array


I have a library developed in C that successfully decompresses an LZMA encoded file. The signature for the file is a pointer to the data, the compressed, decompressed, and an 'out' field for the error code. The return value is a pointer to the array (or null if it fails).

The function in C looks similar to this:

char* decompressLZMA(const char *lzmaData, int compressedSize, int uncompressedSize, t_status_codes *statusCode);

I've tried using pointers and memory from other examples but they are not working.

How do I properly pass a byte array and pointer in to get data back?

This is my interface:

public interface LZMALibrary extends Library {
    Memory lzma_uncompress(Memory lzma_data, int compressed_size, int uncompressed_size, Pointer status_code);
}

Solution

  • It appears that I wanted to make a pointer of the 'Memory' class instead. The solution that is working for me right now is to create Pointer objects, and then the library will fill up the pointers, and I get them back and handle it appropriately.

    My interface turned to:

    public interface LZMALibrary extends Library {
        Pointer lzma_uncompress(Pointer lzma_data, int compressed_size, int uncompressed_size, Pointer status_code);
    }
    

    From there I am able to write in the data:

    Pointer ptr = new Memory(lzmaData.length);
    ptr.write(0, lzmaData, 0, lzmaData.length);
    

    I also need the pointer that will be written to:

    Pointer errorStatus = new Memory(4);
    

    Then I can call the function to get a pointer back, and read that pointer if it's not null:

    Pointer p = lzmaLib.lzma_uncompress(ptr, lzmaData.length, DECOMPRESSED_LENGTH, errorStatus); // DECOMPRESSED_LENGTH is a constant.
    
    if (p != null) {
        byte[] decompressedData = p.getByteArray(0, DECOMPRESSED_LENGTH);
        System.out.println(new String(decompressedData, "ASCII")); // My data is ASCII text.
    }
    
    if (errorStatus != null) {
        int errorStatusCode = errorStatus.getInt(0);
        System.out.println("Error code: " + errorStatusCode);
    }
    

    This appears to have solved my problem. I am very new to JNA so hopefully I am not missing anything.

    If there's any possible errors I might run into, please feel free to post on how to correct it.