Search code examples
javacallbackjna

JAVA-JNA : I can't modify a structure field throughout a callback function


I have a problem with JNA callbacks. In my JAVA program I use a function pointer that will be called by a native library. This function pointer is:

public int callback(S_CODELINE_INFO codelineInfo)
{
    try
    {
    String codeline=new String(codelineInfo.CodelineRead);
    System.out.println("Codeline document : "+codeline); // Reading from DLL is ok

    // Set field Sorter (JAVA --> DLL)
    codelineInfo.writeField("Sorter", 9); // Writing is KO. The sorted field (sort type) is always equal to 0

    }catch(Exception exp)
    {

    exp.printStackTrace();
    }

    return 0;
}

_CODELINE_INFO structure :

public class S_CODELINE_INFO extends Structure
{
   /************** Parameters compiled from LS500.dll ************************/

    // Size of the struct
    public short Size;  

    // Progessive document number
    public NativeLong NrDoc;

    // Codeline returned    
    public byte[] CodelineRead=new byte[39];    

    // Length of the codeline
    public short NrBytes;   

    // Reserved for future use
    public NativeLong Reserved;                     

    /****************** Parameters compiled from Application *********************/

    // Sorter where put the document
    public short Sorter;    

    // Set from application NORMAL or BOLD
    public byte FormatString;       

    // String to print rear of the document
    public String StringToPrint;

    public S_CODELINE_INFO()
    {
        super();
    }

    @Override
    protected List<String> getFieldOrder() 
    {
        return Arrays.asList(new String[]{
            "Size", "NrDoc", "CodelineRead", "NrBytes", "Reserved", "Sorter","FormatString", "StringToPrint"        
        });
    }

    public static class ByReference extends S_CODELINE_INFO implements Structure.ByReference{};

}

Solution

  • You are modifying the structure, just not in the way you intended.

    JNA's Structure class maps its Java fields to appropriate offsets in native memory for the C struct equivalent.

    In this case, the way you have defined the structure, you are attempting to write the Sorter field, a short (2-byte) field at an offset of 51 bytes from the beginning of the structure.

    However, this may not be where Sorter is on the native side. I'm not sure where your 39 came from, but the native code I see online has:

    char CodelineRead[CODE_LINE_LENGTH]; // Codeline returned
    

    With that value defined:

    #define CODE_LINE_LENGTH 256 // Max length of returned codeline
    

    So writing at bytes 51-52 doesn't work since you're writing in the middle of the CodeLineRead array on the native side.