From 1d92893c059dc5d24acd4adbe41259ab393c606b Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 22 Jan 2018 12:51:04 +0300 Subject: [PATCH] jni: register_native_method. Fail if class/method not found. GitOrigin-RevId: d4ea78919a2f43420dfdb2e59326c6511265d70a --- td/generate/tl_writer_jni_cpp.cpp | 9 +---- td/generate/tl_writer_jni_h.cpp | 3 +- td/tl/tl_jni_object.cpp | 64 +++++++++++++++---------------- td/tl/tl_jni_object.h | 16 ++++---- 4 files changed, 44 insertions(+), 48 deletions(-) diff --git a/td/generate/tl_writer_jni_cpp.cpp b/td/generate/tl_writer_jni_cpp.cpp index a3f0edd45..e0b628ccb 100644 --- a/td/generate/tl_writer_jni_cpp.cpp +++ b/td/generate/tl_writer_jni_cpp.cpp @@ -563,11 +563,6 @@ std::string TD_TL_writer_jni_cpp::gen_additional_function(const std::string &fun class_name_class + " = jni::get_jclass(env, " + gen_java_class_name(gen_class_name(t->name)) + ");\n"; if (t->args.size()) { - res += - "\n" - " if (" + - class_name_class + ") {\n"; - for (std::size_t i = 0; i < t->args.size(); i++) { const tl::arg &a = t->args[i]; assert(a.type->get_type() == tl::NODE_TYPE_TYPE); @@ -593,11 +588,9 @@ std::string TD_TL_writer_jni_cpp::gen_additional_function(const std::string &fun } type_signature = new_type_signature + ").c_str()"; } - res += " " + field_name + "fieldID = jni::get_field_id(env, " + class_name_class + ", \"" + java_field_name + + res += " " + field_name + "fieldID = jni::get_field_id(env, " + class_name_class + ", \"" + java_field_name + "\", " + type_signature + ");\n"; } - - res += " }\n"; } res += "}\n"; return res; diff --git a/td/generate/tl_writer_jni_h.cpp b/td/generate/tl_writer_jni_h.cpp index 3dcc1435f..d974d454d 100644 --- a/td/generate/tl_writer_jni_h.cpp +++ b/td/generate/tl_writer_jni_h.cpp @@ -118,7 +118,8 @@ std::string TD_TL_writer_jni_h::gen_class_begin(const std::string &class_name, c " {\n" " public:\n" " virtual ~" + - class_name + "() {\n" + class_name + + "() {\n" " }\n\n" + " virtual void store(JNIEnv *env, jobject &s) const {\n" " }\n\n" diff --git a/td/tl/tl_jni_object.cpp b/td/tl/tl_jni_object.cpp index a4846c625..a93ca546b 100644 --- a/td/tl/tl_jni_object.cpp +++ b/td/tl/tl_jni_object.cpp @@ -9,6 +9,9 @@ #include "td/utils/common.h" #include "td/utils/logging.h" #include "td/utils/misc.h" +#include "td/utils/Slice.h" + +#include namespace td { namespace jni { @@ -29,51 +32,51 @@ jmethodID IntegerGetValueMethodID; jmethodID LongGetValueMethodID; jmethodID DoubleGetValueMethodID; +static void fatal_error(JNIEnv *env, CSlice error) { + LOG(ERROR) << error; + env->FatalError(error.c_str()); +} + jclass get_jclass(JNIEnv *env, const char *class_name) { jclass clazz = env->FindClass(class_name); if (!clazz) { - LOG(INFO) << "Can't find class [" << class_name << "]"; - env->ExceptionClear(); - return clazz; + fatal_error(env, PSLICE() << "Can't find class [" << class_name << "]"); } jclass clazz_global = (jclass)env->NewGlobalRef(clazz); env->DeleteLocalRef(clazz); if (!clazz_global) { - LOG(ERROR) << "Can't create global reference to [" << class_name << "]"; - env->FatalError("Can't create global reference"); + fatal_error(env, PSLICE() << "Can't create global reference to [" << class_name << "]"); } return clazz_global; } -jmethodID get_method_id(JNIEnv *env, jclass clazz, const char *name, const char *sig) { - if (clazz) { - jmethodID res = env->GetMethodID(clazz, name, sig); - if (res) { - return res; - } - - LOG(ERROR) << "Can't find method [" << name << "] with signature [" << sig << "]"; - env->FatalError("Can't find method"); +jmethodID get_method_id(JNIEnv *env, jclass clazz, const char *name, const char *signature) { + jmethodID res = env->GetMethodID(clazz, name, signature); + if (!res) { + fatal_error(env, PSLICE() << "Can't find method [" << name << "] with signature [" << signature << "]"); } - return nullptr; + return res; } -jfieldID get_field_id(JNIEnv *env, jclass clazz, const char *name, const char *sig) { - // TODO check clazz != nullptr on call - jfieldID res = env->GetFieldID(clazz, name, sig); - if (res) { - return res; +jfieldID get_field_id(JNIEnv *env, jclass clazz, const char *name, const char *signature) { + jfieldID res = env->GetFieldID(clazz, name, signature); + if (!res) { + fatal_error(env, PSLICE() << "Can't find field [" << name << "] with signature [" << signature << "]"); } - - LOG(ERROR) << "Can't find field [" << name << "] with signature [" << sig << "]"; - env->FatalError("Can't find field"); - return 0; + return res; } -bool init_vars(JNIEnv *env, const char *td_api_java_package) { +void register_native_method(JNIEnv *env, jclass clazz, std::string name, std::string signature, void *function_ptr) { + JNINativeMethod native_method{&name[0], &signature[0], function_ptr}; + if (env->RegisterNatives(clazz, &native_method, 1) != 0) { + fatal_error(env, PSLICE() << "RegisterNatives failed for " << name << " with signature " << signature); + } +} + +void init_vars(JNIEnv *env, const char *td_api_java_package) { BooleanClass = get_jclass(env, "java/lang/Boolean"); IntegerClass = get_jclass(env, "java/lang/Integer"); LongClass = get_jclass(env, "java/lang/Long"); @@ -89,7 +92,6 @@ bool init_vars(JNIEnv *env, const char *td_api_java_package) { IntegerGetValueMethodID = get_method_id(env, IntegerClass, "intValue", "()I"); LongGetValueMethodID = get_method_id(env, LongClass, "longValue", "()J"); DoubleGetValueMethodID = get_method_id(env, DoubleClass, "doubleValue", "()D"); - return true; } static size_t get_utf8_from_utf16_length(const jchar *p, jsize len) { @@ -105,7 +107,7 @@ static size_t get_utf8_from_utf16_length(const jchar *p, jsize len) { } } - // TODO wrong UTF-16 + LOG(FATAL) << "Receive wrong UTF-16 string"; return 0; } result += 1 + (cur >= 0x80) + (cur >= 0x800); @@ -218,11 +220,9 @@ jstring to_jstring(JNIEnv *env, const std::string &s) { return env->NewString(result, result_len); } - jchar *result = new jchar[result_len]; - utf8_to_utf16(s.c_str(), s.size(), result); - jstring result_jstring = env->NewString(result, result_len); - delete[] result; - return result_jstring; + auto result = std::make_unique(result_len); + utf8_to_utf16(s.c_str(), s.size(), result.get()); + return env->NewString(result.get(), result_len); } std::string from_bytes(JNIEnv *env, jbyteArray arr) { diff --git a/td/tl/tl_jni_object.h b/td/tl/tl_jni_object.h index da83e8405..4c65e90e5 100644 --- a/td/tl/tl_jni_object.h +++ b/td/tl/tl_jni_object.h @@ -31,6 +31,14 @@ extern jmethodID IntegerGetValueMethodID; extern jmethodID LongGetValueMethodID; extern jmethodID DoubleGetValueMethodID; +jclass get_jclass(JNIEnv *env, const char *class_name); + +jmethodID get_method_id(JNIEnv *env, jclass clazz, const char *name, const char *signature); + +jfieldID get_field_id(JNIEnv *env, jclass clazz, const char *name, const char *signature); + +void register_native_method(JNIEnv *env, jclass clazz, std::string name, std::string signature, void *function_ptr); + std::string fetch_string(JNIEnv *env, jobject o, jfieldID id); inline jobject fetch_object(JNIEnv *env, const jobject &o, const jfieldID &id) { @@ -54,13 +62,7 @@ std::string from_bytes(JNIEnv *env, jbyteArray arr); jbyteArray to_bytes(JNIEnv *env, const std::string &b); -jclass get_jclass(JNIEnv *env, const char *class_name); - -jmethodID get_method_id(JNIEnv *env, jclass clazz, const char *name, const char *sig); - -jfieldID get_field_id(JNIEnv *env, jclass clazz, const char *name, const char *sig); - -bool init_vars(JNIEnv *env, const char *td_api_java_package); +void init_vars(JNIEnv *env, const char *td_api_java_package); jintArray store_vector(JNIEnv *env, const std::vector &v);