Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitaaf9896

Browse files
committed
Fixed dropping of GreetingSet
We were incorrectly passing GreetingSet by value, which was causing problems when we tried to free it.
1 parent82fd3a2 commitaaf9896

File tree

5 files changed

+32
-17
lines changed

5 files changed

+32
-17
lines changed

‎src/main/java/com/github/drrb/javarust/Greeting.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ protected List<String> getFieldOrder() {
4949

5050
@Override
5151
publicvoidclose() {
52+
// Turn off "auto-synch". If it is on, JNA will automatically read all fields
53+
// from the struct's memory and update them on the Java object. This synchronization
54+
// occurs after every native method call. If it occurs after we drop the struct, JNA
55+
// will try to read from the freed memory and cause a segmentation fault.
56+
setAutoSynch(false);
5257
// Send the struct back to rust for the memory to be freed
5358
Greetings.INSTANCE.dropGreeting(this);
5459
}

‎src/main/java/com/github/drrb/javarust/GreetingSet.java

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,12 @@
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-
publicclassGreetingSetextendsStructure {
29+
publicclassGreetingSetextendsStructureimplementsCloseable{
3030

3131
publicstaticclassByReferenceextendsGreetingSetimplementsStructure.ByReference {
3232
}
3333

34-
publicstaticclassByValueextendsGreetingSetimplementsStructure.ByValue,Closeable {
35-
36-
@Override
37-
publicvoidclose() {
38-
Greetings.INSTANCE.dropGreetingSet(this);
39-
}
40-
34+
publicstaticclassByValueextendsGreetingSetimplementsStructure.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.theif 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
publicGreeting.ByReferencegreetings;
@@ -88,4 +82,20 @@ public List<Greeting> getGreetings() {
8882
protectedList<String>getFieldOrder() {
8983
returnArrays.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+
publicvoidclose() {
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
}

‎src/main/java/com/github/drrb/javarust/Greetings.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ public interface Greetings extends Library {
7676
* This is the same as returning a {@link GreetingSet.ByReference}. JNA assumes
7777
* it's by reference when it's returned from a native function.
7878
*/
79-
GreetingSet.ByValuerenderGreetings();
79+
GreetingSetrenderGreetings();
8080

8181
/**
8282
* Passing a callback that will be called from Rust with individual strings
@@ -116,5 +116,5 @@ interface GreetingSetCallback extends Callback {
116116
/**
117117
* Free the memory used by a GreetingSet
118118
*/
119-
voiddropGreetingSet(GreetingSet.ByValuegreetingSet);
119+
voiddropGreetingSet(GreetingSetgreetingSet);
120120
}

‎src/main/rust/com/github/drrb/javarust/lib/greetings.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -158,12 +158,12 @@ pub extern fn sendGreetings(callback: extern "C" fn(&GreetingSet)) {
158158
/// Example of returning a more complicated struct from Rust
159159
#[no_mangle]
160160
#[allow(non_snake_case)]
161-
pubexternfnrenderGreetings() ->GreetingSet{
161+
pubexternfnrenderGreetings() ->Box<GreetingSet>{
162162
let greetings =vec![Greeting::new("Hello!"),Greeting::new("Hello again!")];
163163

164-
GreetingSet{
164+
Box::new(GreetingSet{
165165
greetings: greetings.into_boxed_slice()
166-
}
166+
})
167167
}
168168

169169
#[no_mangle]
@@ -175,7 +175,7 @@ pub extern fn dropGreeting(_: Box<Greeting>) {
175175

176176
#[no_mangle]
177177
#[allow(non_snake_case)]
178-
pubexternfndropGreetingSet(_:GreetingSet){
178+
pubexternfndropGreetingSet(_:Box<GreetingSet>){
179179
// Do nothing here. Because we own the GreetingSet here and we're not
180180
// returning it, Rust will assume we don't want it anymore and clean it up.
181181
}

‎src/test/java/com/github/drrb/javarust/GreetingsTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ public void apply(GreetingSet.ByReference greetingSet) {
9797
});
9898

9999
List<String>greetingStrings =newLinkedList<>();
100-
for (Greetinggreeting:greetings) {
100+
for (Greetinggreeting:greetings) {
101101
greetingStrings.add(greeting.getText());
102102
}
103103

@@ -106,7 +106,7 @@ public void apply(GreetingSet.ByReference greetingSet) {
106106

107107
@Test
108108
publicvoidshouldGetAStructFromRustContainingAnArrayOfStructs() {
109-
try (GreetingSet.ByValueresult =library.renderGreetings()) {
109+
try (GreetingSetresult =library.renderGreetings()) {
110110
List<String>greetings =newLinkedList<>();
111111
for (Greetinggreeting :result.getGreetings()) {
112112
greetings.add(greeting.getText());

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp