Skip to content

Commit

Permalink
* Fix Pointer losing its owner when mistakenly ignoring deallocato…
Browse files Browse the repository at this point in the history
…rs for `const` values returned from adapters
  • Loading branch information
saudet committed Feb 25, 2020
1 parent e6ea811 commit 55e3bdc
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 12 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@

* Fix `Pointer` losing its owner when mistakenly ignoring deallocators for `const` values returned from adapters
* Remove unnecessary declared `Exception` from `Indexer.close()` signature ([pull #382](https://github.com/bytedeco/javacpp/pull/382))
* Make sure `Parser` recognizes base classes of `struct` as `public` by default
* Fix `Parser` error on initializer lists containing C++11 style `{ ... }` for template instances
Expand Down
22 changes: 10 additions & 12 deletions src/main/java/org/bytedeco/javacpp/tools/Generator.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2011-2019 Samuel Audet
* Copyright (C) 2011-2020 Samuel Audet
*
* Licensed either under the Apache License, Version 2.0, or (at your option)
* under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -889,7 +889,7 @@ boolean classes(boolean handleExceptions, boolean defineAdapters, boolean conver
out.println("}");
out.println();
out.println("static JavaCPP_noinline void JavaCPP_initPointer(JNIEnv* env, jobject obj, const void* ptr, jlong size, void* owner, void (*deallocator)(void*)) {");
out.println(" if (deallocator != NULL) {");
out.println(" if (owner != NULL && deallocator != NULL) {");
out.println(" jvalue args[4];");
out.println(" args[0].j = ptr_to_jlong(ptr);");
out.println(" args[1].j = size;");
Expand Down Expand Up @@ -1104,9 +1104,9 @@ boolean classes(boolean handleExceptions, boolean defineAdapters, boolean conver
out.println(" }");
out.println(" operator signed char*() { return (signed char*)(operator char*)(); }");
out.println(" operator unsigned char*() { return (unsigned char*)(operator char*)(); }");
out.println(" operator const char*() { return str.c_str(); }");
out.println(" operator const signed char*() { return (signed char*)str.c_str(); }");
out.println(" operator const unsigned char*() { return (unsigned char*)str.c_str(); }");
out.println(" operator const char*() { size = str.size(); return str.c_str(); }");
out.println(" operator const signed char*() { size = str.size(); return (signed char*)str.c_str(); }");
out.println(" operator const unsigned char*() { size = str.size(); return (unsigned char*)str.c_str(); }");
out.println(" operator wchar_t*() {");
out.println(" const wchar_t* data = str.data();");
out.println(" if (str.size() > size) {");
Expand All @@ -1123,9 +1123,9 @@ boolean classes(boolean handleExceptions, boolean defineAdapters, boolean conver
out.println(" }");
out.println(" operator unsigned short*() { return (unsigned short*)(operator wchar_t*)(); }");
out.println(" operator signed int*() { return ( signed int*)(operator wchar_t*)(); }");
out.println(" operator const wchar_t*() { return str.c_str(); }");
out.println(" operator const unsigned short*() { return (unsigned short*)str.c_str(); }");
out.println(" operator const signed int*() { return ( signed int*)str.c_str(); }");
out.println(" operator const wchar_t*() { size = str.size(); return str.c_str(); }");
out.println(" operator const unsigned short*() { size = str.size(); return (unsigned short*)str.c_str(); }");
out.println(" operator const signed int*() { size = str.size(); return ( signed int*)str.c_str(); }");
out.println(" operator std::basic_string<T>&() { return str; }");
out.println(" operator std::basic_string<T>*() { return ptr ? &str : 0; }");
out.println(" T* ptr;");
Expand Down Expand Up @@ -2470,11 +2470,9 @@ void returnAfter(MethodInformation methodInfo) {
out.println(indent + "jlong rcapacity = (jlong)radapter.size;");
if (Pointer.class.isAssignableFrom(methodInfo.returnType)) {
out.println(indent + "void* rowner = radapter.owner;");
}
if (typeName[0].startsWith("const ")) {
out.println(indent + "void (*deallocator)(void*) = 0;");
out.println(indent + "void (*deallocator)(void*) = rowner != NULL ? &" + adapterInfo.name + "::deallocate : 0;");
} else {
out.println(indent + "void (*deallocator)(void*) = &" + adapterInfo.name + "::deallocate;");
out.println(indent + "void (*deallocator)(void*) = 0;");
}
}
needInit = true;
Expand Down
6 changes: 6 additions & 0 deletions src/test/java/org/bytedeco/javacpp/AdapterTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

import java.io.File;
import java.nio.IntBuffer;
import org.bytedeco.javacpp.annotation.ByRef;
import org.bytedeco.javacpp.annotation.Cast;
import org.bytedeco.javacpp.annotation.Const;
import org.bytedeco.javacpp.annotation.Function;
Expand Down Expand Up @@ -58,6 +59,8 @@ public class AdapterTest {

static native IntPointer testIntString(IntPointer str);

static native @Const @ByRef @StdString byte[] getConstStdString();

static class SharedData extends Pointer {
SharedData(Pointer p) { super(p); }
SharedData(int data) { allocate(data); }
Expand Down Expand Up @@ -137,6 +140,9 @@ static class UniqueData extends Pointer {
assertEquals(textStr1, textIntPtr1.getString());
assertEquals(textStr1, textIntPtr2.getString());
}

byte[] test = getConstStdString();
assertEquals("test", new String(test));
System.gc();
}

Expand Down
5 changes: 5 additions & 0 deletions src/test/resources/org/bytedeco/javacpp/AdapterTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ int *testIntString(int *str) {
return str;
}

const std::string& getConstStdString() {
static std::string test("test");
return test;
}

int constructorCount = 0;
int destructorCount = 0;

Expand Down

0 comments on commit 55e3bdc

Please sign in to comment.