2626 * A struct that contains an array of structs. This is the Java representation
2727 * of the GreetingSet struct in Rust (see the Rust code).
2828 */
29- public class GreetingSet extends Structure {
29+ public class GreetingSet extends Structure implements Closeable {
3030
3131 public static class ByReference extends GreetingSet implements Structure .ByReference {
3232 }
3333
34- public static class ByValue extends GreetingSet implements Structure .ByValue , Closeable {
35-
36- @ Override
37- public void close () {
38- Greetings .INSTANCE .dropGreetingSet (this );
39- }
40-
34+ public static class ByValue extends GreetingSet implements Structure .ByValue {
4135 }
4236
4337 /**
@@ -48,7 +42,7 @@ public void close() {
4842 *
4943 * NB: We need to explicitly specify that the field is a pointer (i.e. we need
5044 * to use ByReference) because, by default, JNA assumes that struct fields
51- * are not pointers (i.e. the if you just say "Greeting", JNA assumes
45+ * are not pointers (i.e. if you just say "Greeting", JNA assumes
5246 * "Greeting.ByValue" here).
5347 */
5448 public Greeting .ByReference greetings ;
@@ -88,4 +82,20 @@ public List<Greeting> getGreetings() {
8882 protected List <String > getFieldOrder () {
8983 return Arrays .asList ("greetings" , "numberOfGreetings" );
9084 }
85+
86+ /**
87+ * Send the GreetingSet back to Rust to be dropped.
88+ *
89+ * We do this because JNA doesn't free the memory when the object is garbage collected.
90+ */
91+ @ Override
92+ public void close () {
93+ // Turn off "auto-synch". If it is on, JNA will automatically read all fields
94+ // from the struct's memory and update them on the Java object. This synchronization
95+ // occurs after every native method call. If it occurs after we drop the struct, JNA
96+ // will try to read from the freed memory and cause a segmentation fault.
97+ setAutoSynch (false );
98+ // Send the struct back to rust for the memory to be freed
99+ Greetings .INSTANCE .dropGreetingSet (this );
100+ }
91101}
0 commit comments