jni: register_native_method. Fail if class/method not found.

GitOrigin-RevId: d4ea78919a2f43420dfdb2e59326c6511265d70a
This commit is contained in:
levlam 2018-01-22 12:51:04 +03:00
parent 704053580f
commit 1d92893c05
4 changed files with 44 additions and 48 deletions

View File

@ -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"; class_name_class + " = jni::get_jclass(env, " + gen_java_class_name(gen_class_name(t->name)) + ");\n";
if (t->args.size()) { if (t->args.size()) {
res +=
"\n"
" if (" +
class_name_class + ") {\n";
for (std::size_t i = 0; i < t->args.size(); i++) { for (std::size_t i = 0; i < t->args.size(); i++) {
const tl::arg &a = t->args[i]; const tl::arg &a = t->args[i];
assert(a.type->get_type() == tl::NODE_TYPE_TYPE); 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()"; 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"; "\", " + type_signature + ");\n";
} }
res += " }\n";
} }
res += "}\n"; res += "}\n";
return res; return res;

View File

@ -118,7 +118,8 @@ std::string TD_TL_writer_jni_h::gen_class_begin(const std::string &class_name, c
" {\n" " {\n"
" public:\n" " public:\n"
" virtual ~" + " virtual ~" +
class_name + "() {\n" class_name +
"() {\n"
" }\n\n" + " }\n\n" +
" virtual void store(JNIEnv *env, jobject &s) const {\n" " virtual void store(JNIEnv *env, jobject &s) const {\n"
" }\n\n" " }\n\n"

View File

@ -9,6 +9,9 @@
#include "td/utils/common.h" #include "td/utils/common.h"
#include "td/utils/logging.h" #include "td/utils/logging.h"
#include "td/utils/misc.h" #include "td/utils/misc.h"
#include "td/utils/Slice.h"
#include <memory>
namespace td { namespace td {
namespace jni { namespace jni {
@ -29,51 +32,51 @@ jmethodID IntegerGetValueMethodID;
jmethodID LongGetValueMethodID; jmethodID LongGetValueMethodID;
jmethodID DoubleGetValueMethodID; 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 get_jclass(JNIEnv *env, const char *class_name) {
jclass clazz = env->FindClass(class_name); jclass clazz = env->FindClass(class_name);
if (!clazz) { if (!clazz) {
LOG(INFO) << "Can't find class [" << class_name << "]"; fatal_error(env, PSLICE() << "Can't find class [" << class_name << "]");
env->ExceptionClear();
return clazz;
} }
jclass clazz_global = (jclass)env->NewGlobalRef(clazz); jclass clazz_global = (jclass)env->NewGlobalRef(clazz);
env->DeleteLocalRef(clazz); env->DeleteLocalRef(clazz);
if (!clazz_global) { if (!clazz_global) {
LOG(ERROR) << "Can't create global reference to [" << class_name << "]"; fatal_error(env, PSLICE() << "Can't create global reference to [" << class_name << "]");
env->FatalError("Can't create global reference");
} }
return clazz_global; return clazz_global;
} }
jmethodID get_method_id(JNIEnv *env, jclass clazz, const char *name, const char *sig) { jmethodID get_method_id(JNIEnv *env, jclass clazz, const char *name, const char *signature) {
if (clazz) { jmethodID res = env->GetMethodID(clazz, name, signature);
jmethodID res = env->GetMethodID(clazz, name, sig); if (!res) {
if (res) { fatal_error(env, PSLICE() << "Can't find method [" << name << "] with signature [" << signature << "]");
return res;
}
LOG(ERROR) << "Can't find method [" << name << "] with signature [" << sig << "]";
env->FatalError("Can't find method");
} }
return nullptr; return res;
} }
jfieldID get_field_id(JNIEnv *env, jclass clazz, const char *name, const char *sig) { jfieldID get_field_id(JNIEnv *env, jclass clazz, const char *name, const char *signature) {
// TODO check clazz != nullptr on call jfieldID res = env->GetFieldID(clazz, name, signature);
jfieldID res = env->GetFieldID(clazz, name, sig); if (!res) {
if (res) { fatal_error(env, PSLICE() << "Can't find field [" << name << "] with signature [" << signature << "]");
return res;
} }
return res;
LOG(ERROR) << "Can't find field [" << name << "] with signature [" << sig << "]";
env->FatalError("Can't find field");
return 0;
} }
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"); BooleanClass = get_jclass(env, "java/lang/Boolean");
IntegerClass = get_jclass(env, "java/lang/Integer"); IntegerClass = get_jclass(env, "java/lang/Integer");
LongClass = get_jclass(env, "java/lang/Long"); 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"); IntegerGetValueMethodID = get_method_id(env, IntegerClass, "intValue", "()I");
LongGetValueMethodID = get_method_id(env, LongClass, "longValue", "()J"); LongGetValueMethodID = get_method_id(env, LongClass, "longValue", "()J");
DoubleGetValueMethodID = get_method_id(env, DoubleClass, "doubleValue", "()D"); DoubleGetValueMethodID = get_method_id(env, DoubleClass, "doubleValue", "()D");
return true;
} }
static size_t get_utf8_from_utf16_length(const jchar *p, jsize len) { 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; return 0;
} }
result += 1 + (cur >= 0x80) + (cur >= 0x800); 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); return env->NewString(result, result_len);
} }
jchar *result = new jchar[result_len]; auto result = std::make_unique<jchar[]>(result_len);
utf8_to_utf16(s.c_str(), s.size(), result); utf8_to_utf16(s.c_str(), s.size(), result.get());
jstring result_jstring = env->NewString(result, result_len); return env->NewString(result.get(), result_len);
delete[] result;
return result_jstring;
} }
std::string from_bytes(JNIEnv *env, jbyteArray arr) { std::string from_bytes(JNIEnv *env, jbyteArray arr) {

View File

@ -31,6 +31,14 @@ extern jmethodID IntegerGetValueMethodID;
extern jmethodID LongGetValueMethodID; extern jmethodID LongGetValueMethodID;
extern jmethodID DoubleGetValueMethodID; 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); std::string fetch_string(JNIEnv *env, jobject o, jfieldID id);
inline jobject fetch_object(JNIEnv *env, const jobject &o, const 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); jbyteArray to_bytes(JNIEnv *env, const std::string &b);
jclass get_jclass(JNIEnv *env, const char *class_name); void init_vars(JNIEnv *env, const char *td_api_java_package);
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);
jintArray store_vector(JNIEnv *env, const std::vector<std::int32_t> &v); jintArray store_vector(JNIEnv *env, const std::vector<std::int32_t> &v);