JNA: set structure pointer to NULL

I am starting to use JNA to communicate with a device on the RS485 interface of a computer. Surprisingly, I quickly achieved good results. But now I'm stuck in a simple problem. The library I use takes a pointer to a pointer to a structure. Actual Signature

func(Struct1 **, Struct2 **, Struct3 *, Struct4 *, long)

Now, to indicate the size of the first parameter, the library expects the last pointer to be a NULL pointer. This is what fails. The following code is what I have tried so far:

  Struct1.ByReference[] s = (Struct1.ByReference[]) new Struct1.ByReference().toArray(size); int pos = 0; // ... // for loop to set the s[pos] struture values for(pos = 0; pos < size - 1; pos++) // ... // Now set the last array element to a null pointer to indicate end-of-list s[pos].getPointer().setPointer(0, null);// Following does not work: results in zero memoried structure s[pos] = null; // Following does not work wither: NullPointerException at com.sun.jna.Structure.autoWrite 

EDIT 1

 s[pos] = new Struct1.ByReference(Pointer.NULL); // results in zero memoried structure as well 

EDIT 2

According to the technical question. If I wrote C code, it would probably look something like this:

 Struct1 **s = malloc(n * sizeof(Struct1*)); for(int i=0; i<n; i++) { if(i == n -1) { s[i] = NULL; } else { s[i] = malloc(sizeof(Struct1)); s[i].bla = value; .... } } 

But be careful: I am not very good at C / C ++. I consider Java my domain.

Has anyone had a similar problem? Maybe I just don’t see a tree for trees ...

Thanks in advance.

+5
source share
1 answer

Structures in JNA are pointers, so you really need a pointer to a (pointer to) a structure, which is a PointerByReference - in your case, an array of them.

Given the above code example, you will create your array of structures, one less than n:

 Struct1[] struct1Array = new Struct1[n-1]; 

This only allocates Java memory for the array.

Then you create and write the changes made to the original memory:

 for (int i = 0; i < n-1; i++) { struct1Array[i] = new Struct1(); struct1Array[i].bla = value; struct1Array[i].write(); } 

new Struct1() allocates internal memory for these structures. To do this, you can use the Structure.toArray() ; I intentionally make it a little more manual and low-level to try to understand what is happening.

You will then create the appropriate PointerByReference array to hold pointers to these structures. You will add an additional element for null:

 PointerByReference[] pbrArray = new PointerByReference[n]; 

Again, this is just a distribution in Java. And then you populate it with pointers to pointers to the structure obtained from the Structure.getPointer() method:

 for (int i = 0; i < n-1; i++) { pbrArray[i] = new PointerByReference(struct1Array[i].getPointer()); } pbrArray[n - 1] = new PointerByReference(Pointer.NULL); 

Here new PointerByReference() allocates internal memory for the pointer itself, which points to the structure of the native part that you previously assigned.

From how I understand your initial question, you will pass this PointerByReference array to your function, which is supposed to update your structures.

Since you created two arrays in this way, you can track their correspondence with the index of the array. You may need to iterate over the array of the structure and read() built-in memory into the structure on the Java side for further processing with it. Usually, when you directly work with Structures, methods passed, they are autowrite and autoread, but when using PointerByReference to indirectly reference a JNA structure, it is not so friendly.

As an alternative to tracking two arrays by the corresponding indexes, you can “forget” the initial purpose of the structure and restore it later using the PointerByReference.getValue() method in your array to restore the memory pointer for the structure and then instantiate a new structure using this a pointer in its constructor (for example, new Struct1(pbr.getValue()) , which calls super() with that pointer).

0
source

Source: https://habr.com/ru/post/1245543/


All Articles