Add td::jni::get_jni_env wrapper.

GitOrigin-RevId: 5cc7cc927d0195bcdc7f8adbeea052266dff6af5
This commit is contained in:
levlam 2018-01-28 13:20:43 +03:00
parent afde0fdcc6
commit 18034f7806
3 changed files with 49 additions and 2 deletions

View File

@ -23,10 +23,10 @@ TDLib (Telegram Database library) is a cross-platform library for building [Tele
* **Easy to use**: `TDLib` takes care of all network implementation details, encryption and local data storage. * **Easy to use**: `TDLib` takes care of all network implementation details, encryption and local data storage.
* **High-performance**: in the [Telegram Bot API](https://core.telegram.org/bots/api), each `TDLib` instance handles more than 18000 active bots simultaneously. * **High-performance**: in the [Telegram Bot API](https://core.telegram.org/bots/api), each `TDLib` instance handles more than 18000 active bots simultaneously.
* **Well-documented**: all `TDLib` API methods and public interfaces are fully documented. * **Well-documented**: all `TDLib` API methods and public interfaces are fully documented.
* **Consistent**: `TDLib` guarantees that all updates will be delivered in the right order. * **Consistent**: `TDLib` guarantees that all updates are delivered in the right order.
* **Reliable**: `TDLib` remains stable on slow and unstable Internet connections. * **Reliable**: `TDLib` remains stable on slow and unstable Internet connections.
* **Secure**: all local data is encrypted using a user-provided encryption key. * **Secure**: all local data is encrypted using a user-provided encryption key.
* **Fully-asynchronous**: requests to `TDLib` don't block each other or anything else, responses will be sent when they are available. * **Fully-asynchronous**: requests to `TDLib` don't block each other or anything else, responses are sent when they are available.
<a name="usage"></a> <a name="usage"></a>
## Examples and documentation ## Examples and documentation

View File

@ -76,6 +76,22 @@ void register_native_method(JNIEnv *env, jclass clazz, std::string name, std::st
} }
} }
std::unique_ptr<JNIEnv, JvmThreadDetacher> get_jni_env(JavaVM *java_vm, jint jni_version) {
JNIEnv *env = nullptr;
if (java_vm->GetEnv(reinterpret_cast<void **>(&env), jni_version) == JNI_EDETACHED) {
#ifdef JDK1_2 // if not Android JNI
auto p_env = reinterpret_cast<void **>(&env);
#else
auto p_env = &env;
#endif
java_vm->AttachCurrentThread(p_env, nullptr);
} else {
java_vm = nullptr;
}
return std::unique_ptr<JNIEnv, JvmThreadDetacher>(env, JvmThreadDetacher(java_vm));
}
void 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"); BooleanClass = get_jclass(env, "java/lang/Boolean");
IntegerClass = get_jclass(env, "java/lang/Integer"); IntegerClass = get_jclass(env, "java/lang/Integer");

View File

@ -39,6 +39,37 @@ jfieldID get_field_id(JNIEnv *env, jclass clazz, const char *name, const char *s
void register_native_method(JNIEnv *env, jclass clazz, std::string name, std::string signature, void *function_ptr); void register_native_method(JNIEnv *env, jclass clazz, std::string name, std::string signature, void *function_ptr);
class JvmThreadDetacher {
JavaVM *java_vm_;
void detach() {
if (java_vm_ != nullptr) {
java_vm_->DetachCurrentThread();
java_vm_ = nullptr;
}
}
public:
explicit JvmThreadDetacher(JavaVM *java_vm): java_vm_(java_vm) {
}
JvmThreadDetacher(const JvmThreadDetacher &other) = delete;
JvmThreadDetacher &operator=(const JvmThreadDetacher &other) = delete;
JvmThreadDetacher(JvmThreadDetacher &&other): java_vm_(other.java_vm_) {
other.java_vm_ = nullptr;
}
JvmThreadDetacher &operator=(JvmThreadDetacher &&other) = delete;
~JvmThreadDetacher() {
detach();
}
void operator()(JNIEnv *env) {
detach();
}
};
std::unique_ptr<JNIEnv, JvmThreadDetacher> get_jni_env(JavaVM *java_vm, jint jni_version);
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) {