diff --git a/src/main/java/org/bytedeco/javacpp/annotation/Adapter.java b/src/main/java/org/bytedeco/javacpp/annotation/Adapter.java index 6369e45e3..6985ab1e1 100644 --- a/src/main/java/org/bytedeco/javacpp/annotation/Adapter.java +++ b/src/main/java/org/bytedeco/javacpp/annotation/Adapter.java @@ -39,4 +39,5 @@ /** The number of arguments that {@link Generator} takes from the method as * arguments to the adapter constructor. */ int argc() default 1; + boolean downcast() default false; } diff --git a/src/main/java/org/bytedeco/javacpp/tools/AdapterInformation.java b/src/main/java/org/bytedeco/javacpp/tools/AdapterInformation.java index f56dc0600..8eaab6f32 100644 --- a/src/main/java/org/bytedeco/javacpp/tools/AdapterInformation.java +++ b/src/main/java/org/bytedeco/javacpp/tools/AdapterInformation.java @@ -27,8 +27,9 @@ * @author Samuel Audet */ class AdapterInformation { - String name; - int argc; - String cast, cast2; - boolean constant; + String name; + int argc; + String cast, cast2; + boolean constant; + boolean downcast; } diff --git a/src/main/java/org/bytedeco/javacpp/tools/Generator.java b/src/main/java/org/bytedeco/javacpp/tools/Generator.java index 653b7d796..307bf75fc 100644 --- a/src/main/java/org/bytedeco/javacpp/tools/Generator.java +++ b/src/main/java/org/bytedeco/javacpp/tools/Generator.java @@ -2801,7 +2801,10 @@ void returnAfter(MethodInformation methodInfo) { } } out.println( "if (rptr != NULL) {"); - out.println(indent + " rarg = JavaCPP_createPointer(env, " + jclasses.index(methodInfo.returnType) + + if (adapterInfo!=null && adapterInfo.downcast) + out.println(indent + " rarg = radapter.createPointer(env);"); + else + out.println(indent + " rarg = JavaCPP_createPointer(env, " + jclasses.index(methodInfo.returnType) + (methodInfo.parameterTypes.length > 0 && methodInfo.parameterTypes[0] == Class.class ? ", arg0);" : ");")); out.println(indent + " if (rarg != NULL) {"); if (needInit) { @@ -2875,7 +2878,7 @@ void parametersAfter(MethodInformation methodInfo) { if ("void*".equals(typeName[0]) && !methodInfo.parameterTypes[j].isAnnotationPresent(Opaque.class)) { typeName[0] = "char*"; } - + // If const array, then use JNI_ABORT to avoid copying unmodified data back to JVM final String releaseArrayFlag; if (cast.contains(" const *") || cast.startsWith("(const ")) { @@ -3851,6 +3854,7 @@ AdapterInformation adapterInformation(boolean out, String valueTypeName, Annotat adapterInfo = new AdapterInformation(); adapterInfo.name = adapter.value(); adapterInfo.argc = adapter.argc(); + adapterInfo.downcast = adapter.downcast(); if (a != adapter) { try { Class cls = a.annotationType(); @@ -3880,7 +3884,7 @@ AdapterInformation adapterInformation(boolean out, String valueTypeName, Annotat cast2 = c.value()[2]; } } - } catch (Exception ex) { + } catch (Exception ex) { logger.warn("Could not invoke the value() method on annotation \"" + a + "\": " + ex); } if (valueTypeName != null && valueTypeName.length() > 0) { diff --git a/src/main/java/org/bytedeco/javacpp/tools/Parser.java b/src/main/java/org/bytedeco/javacpp/tools/Parser.java index f41309a02..4395e837a 100644 --- a/src/main/java/org/bytedeco/javacpp/tools/Parser.java +++ b/src/main/java/org/bytedeco/javacpp/tools/Parser.java @@ -671,7 +671,7 @@ Type type(Context context, boolean definition) throws ParserException { } type.cppName += separator; Info info = infoMap.getFirst(t.cppName); - String s = info != null && info.cppTypes != null ? info.cppTypes[0] : t.cppName; + String s = info != null && info.cppTypes != null && info.cppTypes.length>0 ? info.cppTypes[0] : t.cppName; if (t.constValue && !s.startsWith("const ")) { s = "const " + s; }