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";
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);
@ -596,8 +591,6 @@ std::string TD_TL_writer_jni_cpp::gen_additional_function(const std::string &fun
res += " " + field_name + "fieldID = jni::get_field_id(env, " + class_name_class + ", \"" + java_field_name +
"\", " + type_signature + ");\n";
}
res += " }\n";
}
res += "}\n";
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"
" public:\n"
" virtual ~" +
class_name + "() {\n"
class_name +
"() {\n"
" }\n\n" +
" virtual void store(JNIEnv *env, jobject &s) const {\n"
" }\n\n"

View File

@ -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 <memory>
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) {
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 res;
}
LOG(ERROR) << "Can't find method [" << name << "] with signature [" << sig << "]";
env->FatalError("Can't find method");
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 << "]");
}
return nullptr;
}
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;
}
LOG(ERROR) << "Can't find field [" << name << "] with signature [" << sig << "]";
env->FatalError("Can't find field");
return 0;
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);
}
}
bool init_vars(JNIEnv *env, const char *td_api_java_package) {
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<jchar[]>(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) {

View File

@ -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<std::int32_t> &v);