[jnigen] Array signatures fix (https://github.com/dart-lang/jnigen/issues/105)
diff --git a/pkgs/jnigen/example/pdfbox_plugin/src/third_party/pdfbox_plugin.c b/pkgs/jnigen/example/pdfbox_plugin/src/third_party/pdfbox_plugin.c index 1aa65a7..7426e2d 100644 --- a/pkgs/jnigen/example/pdfbox_plugin/src/third_party/pdfbox_plugin.c +++ b/pkgs/jnigen/example/pdfbox_plugin/src/third_party/pdfbox_plugin.c
@@ -947,7 +947,7 @@ if (_c_PDDocument == NULL) return (JniResult){.result = {.j = 0}, .exception = check_exception()}; load_static_method(_c_PDDocument, &_m_PDDocument__load13, "load", - "(L[B;)Lorg/apache/pdfbox/pdmodel/PDDocument;"); + "([B)Lorg/apache/pdfbox/pdmodel/PDDocument;"); if (_m_PDDocument__load13 == NULL) return (JniResult){.result = {.j = 0}, .exception = check_exception()}; jobject _result = (*jniEnv)->CallStaticObjectMethod( @@ -965,7 +965,7 @@ return (JniResult){.result = {.j = 0}, .exception = check_exception()}; load_static_method( _c_PDDocument, &_m_PDDocument__load14, "load", - "(L[B;Ljava/lang/String;)Lorg/apache/pdfbox/pdmodel/PDDocument;"); + "([BLjava/lang/String;)Lorg/apache/pdfbox/pdmodel/PDDocument;"); if (_m_PDDocument__load14 == NULL) return (JniResult){.result = {.j = 0}, .exception = check_exception()}; jobject _result = (*jniEnv)->CallStaticObjectMethod( @@ -985,7 +985,7 @@ if (_c_PDDocument == NULL) return (JniResult){.result = {.j = 0}, .exception = check_exception()}; load_static_method(_c_PDDocument, &_m_PDDocument__load15, "load", - "(L[B;Ljava/lang/String;Ljava/io/InputStream;Ljava/lang/" + "([BLjava/lang/String;Ljava/io/InputStream;Ljava/lang/" "String;)Lorg/apache/pdfbox/pdmodel/PDDocument;"); if (_m_PDDocument__load15 == NULL) return (JniResult){.result = {.j = 0}, .exception = check_exception()}; @@ -1007,10 +1007,10 @@ load_class_gr(&_c_PDDocument, "org/apache/pdfbox/pdmodel/PDDocument"); if (_c_PDDocument == NULL) return (JniResult){.result = {.j = 0}, .exception = check_exception()}; - load_static_method(_c_PDDocument, &_m_PDDocument__load16, "load", - "(L[B;Ljava/lang/String;Ljava/io/InputStream;Ljava/lang/" - "String;Lorg/apache/pdfbox/io/MemoryUsageSetting;)Lorg/" - "apache/pdfbox/pdmodel/PDDocument;"); + load_static_method( + _c_PDDocument, &_m_PDDocument__load16, "load", + "([BLjava/lang/String;Ljava/io/InputStream;Ljava/lang/String;Lorg/apache/" + "pdfbox/io/MemoryUsageSetting;)Lorg/apache/pdfbox/pdmodel/PDDocument;"); if (_m_PDDocument__load16 == NULL) return (JniResult){.result = {.j = 0}, .exception = check_exception()}; jobject _result = (*jniEnv)->CallStaticObjectMethod( @@ -1355,7 +1355,7 @@ if (_c_PDDocument == NULL) return (JniResult){.result = {.j = 0}, .exception = check_exception()}; load_static_field(_c_PDDocument, &_f_PDDocument__RESERVE_BYTE_RANGE, - "RESERVE_BYTE_RANGE", "L[I;"); + "RESERVE_BYTE_RANGE", "[I"); jobject _result = to_global_ref((*jniEnv)->GetStaticObjectField( jniEnv, _c_PDDocument, _f_PDDocument__RESERVE_BYTE_RANGE)); return (JniResult){.result = {.l = _result}, .exception = check_exception()}; @@ -4527,7 +4527,7 @@ return (JniResult){.result = {.j = 0}, .exception = check_exception()}; load_static_field(_c_PDFTextStripper, &_f_PDFTextStripper__LIST_ITEM_EXPRESSIONS, - "LIST_ITEM_EXPRESSIONS", "L[java/lang/String;"); + "LIST_ITEM_EXPRESSIONS", "[Ljava/lang/String;"); jobject _result = to_global_ref((*jniEnv)->GetStaticObjectField( jniEnv, _c_PDFTextStripper, _f_PDFTextStripper__LIST_ITEM_EXPRESSIONS)); return (JniResult){.result = {.l = _result}, .exception = check_exception()};
diff --git a/pkgs/jnigen/lib/src/bindings/c_bindings.dart b/pkgs/jnigen/lib/src/bindings/c_bindings.dart index bc3d61c..8a989d3 100644 --- a/pkgs/jnigen/lib/src/bindings/c_bindings.dart +++ b/pkgs/jnigen/lib/src/bindings/c_bindings.dart
@@ -166,7 +166,7 @@ $_loadEnvCall ${_loadClassCall(classVar, getInternalName(c.binaryName))} load_${ifStaticField}field($classVar, &$fieldVar, "$fieldName", - "${_fieldSignature(f)}"); + "${getDescriptor(f.type)}"); $accessorStatements }\n\n'''); } @@ -256,14 +256,6 @@ '.exception = $exceptionPart};'; } - String _fieldSignature(Field f) { - final internalName = getInternalNameOfUsage(f.type); - if (internalName.length == 1) { - return internalName; - } - return 'L$internalName;'; - } - /// Returns capitalized java type name to be used as in call${type}Method /// or get${type}Field etc.. String _typeNameAtCallSite(TypeUsage type) {
diff --git a/pkgs/jnigen/lib/src/bindings/common.dart b/pkgs/jnigen/lib/src/bindings/common.dart index b7df2be..6945456 100644 --- a/pkgs/jnigen/lib/src/bindings/common.dart +++ b/pkgs/jnigen/lib/src/bindings/common.dart
@@ -308,28 +308,52 @@ } } -String getInternalNameOfUsage(TypeUsage usage, - {bool escapeDollarSign = false}) { +String getSignature(String binaryName) { + switch (binaryName) { + case "void": + return "V"; + case "byte": + return "B"; + case "char": + return "C"; + case "double": + return "D"; + case "float": + return "F"; + case "int": + return "I"; + case "long": + return "J"; + case "short": + return "S"; + case "boolean": + return "Z"; + default: + return 'L${binaryName.replaceAll(".", "/")};'; + } +} + +String getDescriptor(TypeUsage usage, {bool escapeDollarSign = false}) { switch (usage.kind) { case Kind.declared: - return getInternalName((usage.type as DeclaredType).binaryName); + return getSignature((usage.type as DeclaredType).binaryName); case Kind.primitive: - return getInternalName((usage.type as PrimitiveType).name); + return getSignature((usage.type as PrimitiveType).name); case Kind.typeVariable: // It should be possible to compute the erasure of a type // in parser itself. // TODO(#23): Use erasure of the type variable here. // This is just a (wrong) placeholder - return "java/lang/Object"; + return "Ljava/lang/Object;"; case Kind.array: - final inner = getInternalNameOfUsage((usage.type as ArrayType).type); + final inner = getDescriptor((usage.type as ArrayType).type); return "[$inner"; case Kind.wildcard: final extendsBound = (usage.type as Wildcard).extendsBound; if (extendsBound != null) { - return getInternalNameOfUsage(extendsBound); + return getDescriptor(extendsBound); } - return 'java/lang/Object'; + return 'Ljava/lang/Object;'; } } @@ -404,19 +428,11 @@ final s = StringBuffer(); s.write('('); for (var param in m.params) { - final type = getInternalNameOfUsage(param.type); - s.write(type.length == 1 ? type : 'L$type;'); + final type = getDescriptor(param.type); + s.write(type); } s.write(')'); - final returnType = getInternalNameOfUsage(m.returnType); - s.write(returnType.length == 1 ? returnType : 'L$returnType;'); + final returnType = getDescriptor(m.returnType); + s.write(returnType); return s.toString(); } - -String getJniSignatureForField(Field f) { - final internalName = getInternalNameOfUsage(f.type); - if (internalName.length == 1) { - return internalName; - } - return 'L$internalName;'; -}
diff --git a/pkgs/jnigen/test/bindings_test.dart b/pkgs/jnigen/test/bindings_test.dart index 2ba5e5e..64ec6ea 100644 --- a/pkgs/jnigen/test/bindings_test.dart +++ b/pkgs/jnigen/test/bindings_test.dart
@@ -81,6 +81,10 @@ expect(Example.addInts(10, 15), equals(25)); }); + test('static methods arrays', () { + expect(Example.addAll(Example.getArr()), 6); + }); + test('instance methods', () { final ex = Example(); expect(ex.getNum(), equals(Example.num));
diff --git a/pkgs/jnigen/test/jackson_core_test/third_party/src/jackson_core_test.c b/pkgs/jnigen/test/jackson_core_test/third_party/src/jackson_core_test.c index 37c0153..dea4555 100644 --- a/pkgs/jnigen/test/jackson_core_test/third_party/src/jackson_core_test.c +++ b/pkgs/jnigen/test/jackson_core_test/third_party/src/jackson_core_test.c
@@ -951,7 +951,7 @@ if (_c_JsonFactory == NULL) return (JniResult){.result = {.j = 0}, .exception = check_exception()}; load_method(_c_JsonFactory, &_m_JsonFactory__createParser4, "createParser", - "(L[B;)Lcom/fasterxml/jackson/core/JsonParser;"); + "([B)Lcom/fasterxml/jackson/core/JsonParser;"); if (_m_JsonFactory__createParser4 == NULL) return (JniResult){.result = {.j = 0}, .exception = check_exception()}; jobject _result = (*jniEnv)->CallObjectMethod( @@ -971,7 +971,7 @@ if (_c_JsonFactory == NULL) return (JniResult){.result = {.j = 0}, .exception = check_exception()}; load_method(_c_JsonFactory, &_m_JsonFactory__createParser5, "createParser", - "(L[B;II)Lcom/fasterxml/jackson/core/JsonParser;"); + "([BII)Lcom/fasterxml/jackson/core/JsonParser;"); if (_m_JsonFactory__createParser5 == NULL) return (JniResult){.result = {.j = 0}, .exception = check_exception()}; jobject _result = (*jniEnv)->CallObjectMethod( @@ -1005,7 +1005,7 @@ if (_c_JsonFactory == NULL) return (JniResult){.result = {.j = 0}, .exception = check_exception()}; load_method(_c_JsonFactory, &_m_JsonFactory__createParser7, "createParser", - "(L[C;)Lcom/fasterxml/jackson/core/JsonParser;"); + "([C)Lcom/fasterxml/jackson/core/JsonParser;"); if (_m_JsonFactory__createParser7 == NULL) return (JniResult){.result = {.j = 0}, .exception = check_exception()}; jobject _result = (*jniEnv)->CallObjectMethod( @@ -1025,7 +1025,7 @@ if (_c_JsonFactory == NULL) return (JniResult){.result = {.j = 0}, .exception = check_exception()}; load_method(_c_JsonFactory, &_m_JsonFactory__createParser8, "createParser", - "(L[C;II)Lcom/fasterxml/jackson/core/JsonParser;"); + "([CII)Lcom/fasterxml/jackson/core/JsonParser;"); if (_m_JsonFactory__createParser8 == NULL) return (JniResult){.result = {.j = 0}, .exception = check_exception()}; jobject _result = (*jniEnv)->CallObjectMethod( @@ -1265,7 +1265,7 @@ return (JniResult){.result = {.j = 0}, .exception = check_exception()}; load_method(_c_JsonFactory, &_m_JsonFactory__createJsonParser4, "createJsonParser", - "(L[B;)Lcom/fasterxml/jackson/core/JsonParser;"); + "([B)Lcom/fasterxml/jackson/core/JsonParser;"); if (_m_JsonFactory__createJsonParser4 == NULL) return (JniResult){.result = {.j = 0}, .exception = check_exception()}; jobject _result = (*jniEnv)->CallObjectMethod( @@ -1286,7 +1286,7 @@ return (JniResult){.result = {.j = 0}, .exception = check_exception()}; load_method(_c_JsonFactory, &_m_JsonFactory__createJsonParser5, "createJsonParser", - "(L[B;II)Lcom/fasterxml/jackson/core/JsonParser;"); + "([BII)Lcom/fasterxml/jackson/core/JsonParser;"); if (_m_JsonFactory__createJsonParser5 == NULL) return (JniResult){.result = {.j = 0}, .exception = check_exception()}; jobject _result = (*jniEnv)->CallObjectMethod( @@ -1445,7 +1445,7 @@ return (JniResult){.result = {.j = 0}, .exception = check_exception()}; load_static_method(_c_JsonFactory_Feature, &_m_JsonFactory_Feature__values, "values", - "()L[com/fasterxml/jackson/core/JsonFactory$Feature;"); + "()[Lcom/fasterxml/jackson/core/JsonFactory$Feature;"); if (_m_JsonFactory_Feature__values == NULL) return (JniResult){.result = {.j = 0}, .exception = check_exception()}; jobject _result = (*jniEnv)->CallStaticObjectMethod( @@ -1672,7 +1672,7 @@ if (_c_JsonParser == NULL) return (JniResult){.result = {.j = 0}, .exception = check_exception()}; load_method(_c_JsonParser, &_m_JsonParser__setRequestPayloadOnError1, - "setRequestPayloadOnError", "(L[B;Ljava/lang/String;)V"); + "setRequestPayloadOnError", "([BLjava/lang/String;)V"); if (_m_JsonParser__setRequestPayloadOnError1 == NULL) return (JniResult){.result = {.j = 0}, .exception = check_exception()}; (*jniEnv)->CallVoidMethod(jniEnv, self_, @@ -2685,7 +2685,7 @@ if (_c_JsonParser == NULL) return (JniResult){.result = {.j = 0}, .exception = check_exception()}; load_method(_c_JsonParser, &_m_JsonParser__getTextCharacters, - "getTextCharacters", "()L[C;"); + "getTextCharacters", "()[C"); if (_m_JsonParser__getTextCharacters == NULL) return (JniResult){.result = {.j = 0}, .exception = check_exception()}; jobject _result = (*jniEnv)->CallObjectMethod( @@ -2963,7 +2963,7 @@ if (_c_JsonParser == NULL) return (JniResult){.result = {.j = 0}, .exception = check_exception()}; load_method(_c_JsonParser, &_m_JsonParser__getBinaryValue, "getBinaryValue", - "(Lcom/fasterxml/jackson/core/Base64Variant;)L[B;"); + "(Lcom/fasterxml/jackson/core/Base64Variant;)[B"); if (_m_JsonParser__getBinaryValue == NULL) return (JniResult){.result = {.j = 0}, .exception = check_exception()}; jobject _result = (*jniEnv)->CallObjectMethod( @@ -2980,7 +2980,7 @@ if (_c_JsonParser == NULL) return (JniResult){.result = {.j = 0}, .exception = check_exception()}; load_method(_c_JsonParser, &_m_JsonParser__getBinaryValue1, "getBinaryValue", - "()L[B;"); + "()[B"); if (_m_JsonParser__getBinaryValue1 == NULL) return (JniResult){.result = {.j = 0}, .exception = check_exception()}; jobject _result = (*jniEnv)->CallObjectMethod(jniEnv, self_, @@ -3365,7 +3365,7 @@ return (JniResult){.result = {.j = 0}, .exception = check_exception()}; load_static_method(_c_JsonParser_Feature, &_m_JsonParser_Feature__values, "values", - "()L[com/fasterxml/jackson/core/JsonParser$Feature;"); + "()[Lcom/fasterxml/jackson/core/JsonParser$Feature;"); if (_m_JsonParser_Feature__values == NULL) return (JniResult){.result = {.j = 0}, .exception = check_exception()}; jobject _result = (*jniEnv)->CallStaticObjectMethod( @@ -3493,7 +3493,7 @@ return (JniResult){.result = {.j = 0}, .exception = check_exception()}; load_static_method(_c_JsonParser_NumberType, &_m_JsonParser_NumberType__values, "values", - "()L[com/fasterxml/jackson/core/JsonParser$NumberType;"); + "()[Lcom/fasterxml/jackson/core/JsonParser$NumberType;"); if (_m_JsonParser_NumberType__values == NULL) return (JniResult){.result = {.j = 0}, .exception = check_exception()}; jobject _result = (*jniEnv)->CallStaticObjectMethod( @@ -3551,7 +3551,7 @@ if (_c_JsonToken == NULL) return (JniResult){.result = {.j = 0}, .exception = check_exception()}; load_static_method(_c_JsonToken, &_m_JsonToken__values, "values", - "()L[com/fasterxml/jackson/core/JsonToken;"); + "()[Lcom/fasterxml/jackson/core/JsonToken;"); if (_m_JsonToken__values == NULL) return (JniResult){.result = {.j = 0}, .exception = check_exception()}; jobject _result = (*jniEnv)->CallStaticObjectMethod(jniEnv, _c_JsonToken, @@ -3633,8 +3633,7 @@ load_class_gr(&_c_JsonToken, "com/fasterxml/jackson/core/JsonToken"); if (_c_JsonToken == NULL) return (JniResult){.result = {.j = 0}, .exception = check_exception()}; - load_method(_c_JsonToken, &_m_JsonToken__asCharArray, "asCharArray", - "()L[C;"); + load_method(_c_JsonToken, &_m_JsonToken__asCharArray, "asCharArray", "()[C"); if (_m_JsonToken__asCharArray == NULL) return (JniResult){.result = {.j = 0}, .exception = check_exception()}; jobject _result = @@ -3650,8 +3649,7 @@ load_class_gr(&_c_JsonToken, "com/fasterxml/jackson/core/JsonToken"); if (_c_JsonToken == NULL) return (JniResult){.result = {.j = 0}, .exception = check_exception()}; - load_method(_c_JsonToken, &_m_JsonToken__asByteArray, "asByteArray", - "()L[B;"); + load_method(_c_JsonToken, &_m_JsonToken__asByteArray, "asByteArray", "()[B"); if (_m_JsonToken__asByteArray == NULL) return (JniResult){.result = {.j = 0}, .exception = check_exception()}; jobject _result =
diff --git a/pkgs/jnigen/test/simple_package_test/java/com/github/dart_lang/jnigen/simple_package/Example.java b/pkgs/jnigen/test/simple_package_test/java/com/github/dart_lang/jnigen/simple_package/Example.java index b2d5259..1b2aaf4 100644 --- a/pkgs/jnigen/test/simple_package_test/java/com/github/dart_lang/jnigen/simple_package/Example.java +++ b/pkgs/jnigen/test/simple_package_test/java/com/github/dart_lang/jnigen/simple_package/Example.java
@@ -4,6 +4,8 @@ package com.github.dart_lang.jnigen.simple_package; +import java.util.Arrays; + public class Example { public static final int ON = 1; public static final int OFF = 0; @@ -28,6 +30,14 @@ return a + b; } + public static Integer[] getArr() { + return new Integer[] {1, 2, 3}; + } + + public static int addAll(Integer[] arr) { + return Arrays.stream(arr).mapToInt(val -> val).sum(); + } + public Example getSelf() { return this; }
diff --git a/pkgs/jnigen/test/simple_package_test/lib/simple_package.dart b/pkgs/jnigen/test/simple_package_test/lib/simple_package.dart index d9f7a42..a31e667 100644 --- a/pkgs/jnigen/test/simple_package_test/lib/simple_package.dart +++ b/pkgs/jnigen/test/simple_package_test/lib/simple_package.dart
@@ -97,6 +97,22 @@ /// from: static public int addInts(int a, int b) static int addInts(int a, int b) => _addInts(a, b).integer; + static final _getArr = + jniLookup<ffi.NativeFunction<jni.JniResult Function()>>("Example__getArr") + .asFunction<jni.JniResult Function()>(); + + /// from: static public java.lang.Integer[] getArr() + /// The returned object must be deleted after use, by calling the `delete` method. + static jni.JniObject getArr() => jni.JniObject.fromRef(_getArr().object); + + static final _addAll = jniLookup< + ffi.NativeFunction< + jni.JniResult Function(ffi.Pointer<ffi.Void>)>>("Example__addAll") + .asFunction<jni.JniResult Function(ffi.Pointer<ffi.Void>)>(); + + /// from: static public int addAll(java.lang.Integer[] arr) + static int addAll(jni.JniObject arr) => _addAll(arr.reference).integer; + static final _getSelf = jniLookup< ffi.NativeFunction< jni.JniResult Function(
diff --git a/pkgs/jnigen/test/simple_package_test/src/simple_package.c b/pkgs/jnigen/test/simple_package_test/src/simple_package.c index c3f4925..c3b82d2 100644 --- a/pkgs/jnigen/test/simple_package_test/src/simple_package.c +++ b/pkgs/jnigen/test/simple_package_test/src/simple_package.c
@@ -89,6 +89,41 @@ return (JniResult){.result = {.i = _result}, .exception = check_exception()}; } +jmethodID _m_Example__getArr = NULL; +FFI_PLUGIN_EXPORT +JniResult Example__getArr() { + load_env(); + load_class_gr(&_c_Example, + "com/github/dart_lang/jnigen/simple_package/Example"); + if (_c_Example == NULL) + return (JniResult){.result = {.j = 0}, .exception = check_exception()}; + load_static_method(_c_Example, &_m_Example__getArr, "getArr", + "()[Ljava/lang/Integer;"); + if (_m_Example__getArr == NULL) + return (JniResult){.result = {.j = 0}, .exception = check_exception()}; + jobject _result = + (*jniEnv)->CallStaticObjectMethod(jniEnv, _c_Example, _m_Example__getArr); + return (JniResult){.result = {.l = to_global_ref(_result)}, + .exception = check_exception()}; +} + +jmethodID _m_Example__addAll = NULL; +FFI_PLUGIN_EXPORT +JniResult Example__addAll(jobject arr) { + load_env(); + load_class_gr(&_c_Example, + "com/github/dart_lang/jnigen/simple_package/Example"); + if (_c_Example == NULL) + return (JniResult){.result = {.j = 0}, .exception = check_exception()}; + load_static_method(_c_Example, &_m_Example__addAll, "addAll", + "([Ljava/lang/Integer;)I"); + if (_m_Example__addAll == NULL) + return (JniResult){.result = {.j = 0}, .exception = check_exception()}; + int32_t _result = (*jniEnv)->CallStaticIntMethod(jniEnv, _c_Example, + _m_Example__addAll, arr); + return (JniResult){.result = {.i = _result}, .exception = check_exception()}; +} + jmethodID _m_Example__getSelf = NULL; FFI_PLUGIN_EXPORT JniResult Example__getSelf(jobject self_) {