You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-04 12:00:25 +00:00
Implement has_java_method(...) for JavaClassWrapper and JNISingleton
This commit is contained in:
@@ -9,4 +9,13 @@
|
|||||||
<tutorials>
|
<tutorials>
|
||||||
<link title="Creating Android plugins">$DOCS_URL/tutorials/platform/android/android_plugin.html#doc-android-plugin</link>
|
<link title="Creating Android plugins">$DOCS_URL/tutorials/platform/android/android_plugin.html#doc-android-plugin</link>
|
||||||
</tutorials>
|
</tutorials>
|
||||||
|
<methods>
|
||||||
|
<method name="has_java_method" qualifiers="const">
|
||||||
|
<return type="bool" />
|
||||||
|
<param index="0" name="method" type="StringName" />
|
||||||
|
<description>
|
||||||
|
Returns [code]true[/code] if the given [param method] name exists in the JNISingleton's Java methods.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
</methods>
|
||||||
</class>
|
</class>
|
||||||
|
|||||||
@@ -29,5 +29,12 @@
|
|||||||
Returns a [JavaClass] representing the Java parent class of this class.
|
Returns a [JavaClass] representing the Java parent class of this class.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="has_java_method" qualifiers="const">
|
||||||
|
<return type="bool" />
|
||||||
|
<param index="0" name="method" type="StringName" />
|
||||||
|
<description>
|
||||||
|
Returns [code]true[/code] if the given [param method] name exists in the object's Java methods.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
</methods>
|
</methods>
|
||||||
</class>
|
</class>
|
||||||
|
|||||||
@@ -17,5 +17,12 @@
|
|||||||
Returns the [JavaClass] that this object is an instance of.
|
Returns the [JavaClass] that this object is an instance of.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="has_java_method" qualifiers="const">
|
||||||
|
<return type="bool" />
|
||||||
|
<param index="0" name="method" type="StringName" />
|
||||||
|
<description>
|
||||||
|
Returns [code]true[/code] if the given [param method] name exists in the object's Java methods.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
</methods>
|
</methods>
|
||||||
</class>
|
</class>
|
||||||
|
|||||||
@@ -62,10 +62,12 @@ void JavaClass::_bind_methods() {
|
|||||||
ClassDB::bind_method(D_METHOD("get_java_class_name"), &JavaClass::get_java_class_name);
|
ClassDB::bind_method(D_METHOD("get_java_class_name"), &JavaClass::get_java_class_name);
|
||||||
ClassDB::bind_method(D_METHOD("get_java_method_list"), &JavaClass::get_java_method_list);
|
ClassDB::bind_method(D_METHOD("get_java_method_list"), &JavaClass::get_java_method_list);
|
||||||
ClassDB::bind_method(D_METHOD("get_java_parent_class"), &JavaClass::get_java_parent_class);
|
ClassDB::bind_method(D_METHOD("get_java_parent_class"), &JavaClass::get_java_parent_class);
|
||||||
|
ClassDB::bind_method(D_METHOD("has_java_method", "method"), &JavaClass::has_java_method);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JavaObject::_bind_methods() {
|
void JavaObject::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("get_java_class"), &JavaObject::get_java_class);
|
ClassDB::bind_method(D_METHOD("get_java_class"), &JavaObject::get_java_class);
|
||||||
|
ClassDB::bind_method(D_METHOD("has_java_method", "method"), &JavaObject::has_java_method);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JavaClassWrapper::_bind_methods() {
|
void JavaClassWrapper::_bind_methods() {
|
||||||
@@ -94,6 +96,10 @@ Ref<JavaClass> JavaClass::get_java_parent_class() const {
|
|||||||
return Ref<JavaClass>();
|
return Ref<JavaClass>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool JavaClass::has_java_method(const StringName &) const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
JavaClass::JavaClass() {
|
JavaClass::JavaClass() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,6 +114,10 @@ Ref<JavaClass> JavaObject::get_java_class() const {
|
|||||||
return Ref<JavaClass>();
|
return Ref<JavaClass>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool JavaObject::has_java_method(const StringName &) const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
JavaClassWrapper *JavaClassWrapper::singleton = nullptr;
|
JavaClassWrapper *JavaClassWrapper::singleton = nullptr;
|
||||||
|
|
||||||
Ref<JavaClass> JavaClassWrapper::_wrap(const String &, bool) {
|
Ref<JavaClass> JavaClassWrapper::_wrap(const String &, bool) {
|
||||||
|
|||||||
@@ -200,6 +200,7 @@ public:
|
|||||||
String get_java_class_name() const;
|
String get_java_class_name() const;
|
||||||
TypedArray<Dictionary> get_java_method_list() const;
|
TypedArray<Dictionary> get_java_method_list() const;
|
||||||
Ref<JavaClass> get_java_parent_class() const;
|
Ref<JavaClass> get_java_parent_class() const;
|
||||||
|
bool has_java_method(const StringName &p_method) const;
|
||||||
|
|
||||||
#ifdef ANDROID_ENABLED
|
#ifdef ANDROID_ENABLED
|
||||||
virtual String to_string() override;
|
virtual String to_string() override;
|
||||||
@@ -226,6 +227,7 @@ public:
|
|||||||
virtual Variant callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) override;
|
virtual Variant callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) override;
|
||||||
|
|
||||||
Ref<JavaClass> get_java_class() const;
|
Ref<JavaClass> get_java_class() const;
|
||||||
|
bool has_java_method(const StringName &p_method) const;
|
||||||
|
|
||||||
#ifdef ANDROID_ENABLED
|
#ifdef ANDROID_ENABLED
|
||||||
virtual String to_string() override;
|
virtual String to_string() override;
|
||||||
@@ -244,7 +246,7 @@ class JavaClassWrapper : public Object {
|
|||||||
#ifdef ANDROID_ENABLED
|
#ifdef ANDROID_ENABLED
|
||||||
RBMap<String, Ref<JavaClass>> class_cache;
|
RBMap<String, Ref<JavaClass>> class_cache;
|
||||||
friend class JavaClass;
|
friend class JavaClass;
|
||||||
jmethodID Class_getDeclaredConstructors;
|
jmethodID Class_getConstructors;
|
||||||
jmethodID Class_getDeclaredMethods;
|
jmethodID Class_getDeclaredMethods;
|
||||||
jmethodID Class_getFields;
|
jmethodID Class_getFields;
|
||||||
jmethodID Class_getName;
|
jmethodID Class_getName;
|
||||||
@@ -272,7 +274,7 @@ class JavaClassWrapper : public Object {
|
|||||||
|
|
||||||
Ref<JavaObject> exception;
|
Ref<JavaObject> exception;
|
||||||
|
|
||||||
Ref<JavaClass> _wrap(const String &p_class, bool p_allow_private_methods_access);
|
Ref<JavaClass> _wrap(const String &p_class, bool p_allow_non_public_methods_access);
|
||||||
|
|
||||||
static JavaClassWrapper *singleton;
|
static JavaClassWrapper *singleton;
|
||||||
|
|
||||||
|
|||||||
@@ -46,35 +46,60 @@ class JNISingleton : public Object {
|
|||||||
RBMap<StringName, MethodData> method_map;
|
RBMap<StringName, MethodData> method_map;
|
||||||
Ref<JavaObject> wrapped_object;
|
Ref<JavaObject> wrapped_object;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static void _bind_methods() {
|
||||||
|
ClassDB::bind_method(D_METHOD("has_java_method", "method"), &JNISingleton::has_java_method);
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual Variant callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) override {
|
virtual Variant callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) override {
|
||||||
if (wrapped_object.is_valid()) {
|
// Godot methods take precedence.
|
||||||
RBMap<StringName, MethodData>::Element *E = method_map.find(p_method);
|
Variant ret = Object::callp(p_method, p_args, p_argcount, r_error);
|
||||||
|
if (r_error.error == Callable::CallError::CALL_OK) {
|
||||||
// Check the method we're looking for is in the JNISingleton map and that
|
return ret;
|
||||||
// the arguments match.
|
|
||||||
bool call_error = !E || E->get().argtypes.size() != p_argcount;
|
|
||||||
if (!call_error) {
|
|
||||||
for (int i = 0; i < p_argcount; i++) {
|
|
||||||
if (!Variant::can_convert(p_args[i]->get_type(), E->get().argtypes[i])) {
|
|
||||||
call_error = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!call_error) {
|
|
||||||
return wrapped_object->callp(p_method, p_args, p_argcount, r_error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Object::callp(p_method, p_args, p_argcount, r_error);
|
// Check the method we're looking for is in the JNISingleton map.
|
||||||
|
RBMap<StringName, MethodData>::Element *E = method_map.find(p_method);
|
||||||
|
if (E) {
|
||||||
|
if (wrapped_object.is_valid()) {
|
||||||
|
// Check that the arguments match.
|
||||||
|
int method_arg_count = E->get().argtypes.size();
|
||||||
|
if (p_argcount < method_arg_count) {
|
||||||
|
r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
|
||||||
|
} else if (p_argcount > method_arg_count) {
|
||||||
|
r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
|
||||||
|
} else {
|
||||||
|
// Check the arguments are valid.
|
||||||
|
bool arguments_valid = true;
|
||||||
|
for (int i = 0; i < p_argcount; i++) {
|
||||||
|
if (!Variant::can_convert(p_args[i]->get_type(), E->get().argtypes[i])) {
|
||||||
|
arguments_valid = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arguments_valid) {
|
||||||
|
return wrapped_object->callp(p_method, p_args, p_argcount, r_error);
|
||||||
|
} else {
|
||||||
|
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
r_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Variant();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<JavaObject> get_wrapped_object() const {
|
Ref<JavaObject> get_wrapped_object() const {
|
||||||
return wrapped_object;
|
return wrapped_object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool has_java_method(const StringName &p_method) const {
|
||||||
|
return method_map.has(p_method);
|
||||||
|
}
|
||||||
|
|
||||||
void add_method(const StringName &p_name, const Vector<Variant::Type> &p_args, Variant::Type p_ret_type) {
|
void add_method(const StringName &p_name, const Vector<Variant::Type> &p_args, Variant::Type p_ret_type) {
|
||||||
MethodData md;
|
MethodData md;
|
||||||
md.argtypes = p_args;
|
md.argtypes = p_args;
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ class AndroidRuntimePlugin(godot: Godot) : GodotPlugin(godot) {
|
|||||||
* Provides access to the host [android.app.Activity] to GDScript
|
* Provides access to the host [android.app.Activity] to GDScript
|
||||||
*/
|
*/
|
||||||
@UsedByGodot
|
@UsedByGodot
|
||||||
override fun getActivity() = super.getActivity()
|
public override fun getActivity() = super.getActivity()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility method used to create [Runnable] from Godot [Callable].
|
* Utility method used to create [Runnable] from Godot [Callable].
|
||||||
|
|||||||
@@ -36,6 +36,7 @@
|
|||||||
bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error, Variant &ret) {
|
bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error, Variant &ret) {
|
||||||
HashMap<StringName, List<MethodInfo>>::Iterator M = methods.find(p_method);
|
HashMap<StringName, List<MethodInfo>>::Iterator M = methods.find(p_method);
|
||||||
if (!M) {
|
if (!M) {
|
||||||
|
r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -756,7 +757,11 @@ bool JavaClass::_get(const StringName &p_name, Variant &r_ret) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Variant JavaClass::callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
|
Variant JavaClass::callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
|
||||||
Variant ret;
|
// Godot methods take precedence.
|
||||||
|
Variant ret = RefCounted::callp(p_method, p_args, p_argcount, r_error);
|
||||||
|
if (r_error.error == Callable::CallError::CALL_OK) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
String method = (p_method == java_constructor_name) ? "<init>" : p_method;
|
String method = (p_method == java_constructor_name) ? "<init>" : p_method;
|
||||||
bool found = _call_method(nullptr, method, p_args, p_argcount, r_error, ret);
|
bool found = _call_method(nullptr, method, p_args, p_argcount, r_error, ret);
|
||||||
@@ -764,7 +769,7 @@ Variant JavaClass::callp(const StringName &p_method, const Variant **p_args, int
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
return RefCounted::callp(p_method, p_args, p_argcount, r_error);
|
return Variant();
|
||||||
}
|
}
|
||||||
|
|
||||||
String JavaClass::get_java_class_name() const {
|
String JavaClass::get_java_class_name() const {
|
||||||
@@ -858,6 +863,11 @@ String JavaClass::to_string() {
|
|||||||
return "<JavaClass:" + java_class_name + ">";
|
return "<JavaClass:" + java_class_name + ">";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool JavaClass::has_java_method(const StringName &p_method) const {
|
||||||
|
String method = (p_method == java_constructor_name) ? "<init>" : p_method;
|
||||||
|
return methods.has(method);
|
||||||
|
}
|
||||||
|
|
||||||
JavaClass::JavaClass() {
|
JavaClass::JavaClass() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -873,10 +883,15 @@ JavaClass::~JavaClass() {
|
|||||||
/////////////////////
|
/////////////////////
|
||||||
|
|
||||||
Variant JavaObject::callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
|
Variant JavaObject::callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
|
||||||
|
// Godot methods take precedence.
|
||||||
|
Variant ret = RefCounted::callp(p_method, p_args, p_argcount, r_error);
|
||||||
|
if (r_error.error == Callable::CallError::CALL_OK) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
if (instance) {
|
if (instance) {
|
||||||
Ref<JavaClass> c = base_class;
|
Ref<JavaClass> c = base_class;
|
||||||
while (c.is_valid()) {
|
while (c.is_valid()) {
|
||||||
Variant ret;
|
|
||||||
bool found = c->_call_method(this, p_method, p_args, p_argcount, r_error, ret);
|
bool found = c->_call_method(this, p_method, p_args, p_argcount, r_error, ret);
|
||||||
if (found) {
|
if (found) {
|
||||||
return ret;
|
return ret;
|
||||||
@@ -885,7 +900,7 @@ Variant JavaObject::callp(const StringName &p_method, const Variant **p_args, in
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return RefCounted::callp(p_method, p_args, p_argcount, r_error);
|
return Variant();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<JavaClass> JavaObject::get_java_class() const {
|
Ref<JavaClass> JavaObject::get_java_class() const {
|
||||||
@@ -899,6 +914,19 @@ String JavaObject::to_string() {
|
|||||||
return RefCounted::to_string();
|
return RefCounted::to_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool JavaObject::has_java_method(const StringName &p_method) const {
|
||||||
|
if (instance) {
|
||||||
|
Ref<JavaClass> c = base_class;
|
||||||
|
while (c.is_valid()) {
|
||||||
|
if (c->has_java_method(p_method)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
c = c->get_java_parent_class();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
JavaObject::JavaObject() {
|
JavaObject::JavaObject() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1461,7 +1489,7 @@ bool JavaClass::_convert_object_to_variant(JNIEnv *env, jobject obj, Variant &va
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<JavaClass> JavaClassWrapper::_wrap(const String &p_class, bool p_allow_private_methods_access) {
|
Ref<JavaClass> JavaClassWrapper::_wrap(const String &p_class, bool p_allow_non_public_methods_access) {
|
||||||
String class_name_dots = p_class.replace_char('/', '.');
|
String class_name_dots = p_class.replace_char('/', '.');
|
||||||
if (class_cache.has(class_name_dots)) {
|
if (class_cache.has(class_name_dots)) {
|
||||||
return class_cache[class_name_dots];
|
return class_cache[class_name_dots];
|
||||||
@@ -1473,10 +1501,18 @@ Ref<JavaClass> JavaClassWrapper::_wrap(const String &p_class, bool p_allow_priva
|
|||||||
jclass bclass = jni_find_class(env, class_name_dots.replace_char('.', '/').utf8().get_data());
|
jclass bclass = jni_find_class(env, class_name_dots.replace_char('.', '/').utf8().get_data());
|
||||||
ERR_FAIL_NULL_V_MSG(bclass, Ref<JavaClass>(), vformat("Java class '%s' not found.", p_class));
|
ERR_FAIL_NULL_V_MSG(bclass, Ref<JavaClass>(), vformat("Java class '%s' not found.", p_class));
|
||||||
|
|
||||||
jobjectArray constructors = (jobjectArray)env->CallObjectMethod(bclass, Class_getDeclaredConstructors);
|
jobjectArray constructors = (jobjectArray)env->CallObjectMethod(bclass, Class_getConstructors);
|
||||||
|
if (env->ExceptionCheck()) {
|
||||||
|
env->ExceptionDescribe();
|
||||||
|
env->ExceptionClear();
|
||||||
|
}
|
||||||
ERR_FAIL_NULL_V(constructors, Ref<JavaClass>());
|
ERR_FAIL_NULL_V(constructors, Ref<JavaClass>());
|
||||||
|
|
||||||
jobjectArray methods = (jobjectArray)env->CallObjectMethod(bclass, Class_getDeclaredMethods);
|
jobjectArray methods = (jobjectArray)env->CallObjectMethod(bclass, Class_getDeclaredMethods);
|
||||||
|
if (env->ExceptionCheck()) {
|
||||||
|
env->ExceptionDescribe();
|
||||||
|
env->ExceptionClear();
|
||||||
|
}
|
||||||
ERR_FAIL_NULL_V(methods, Ref<JavaClass>());
|
ERR_FAIL_NULL_V(methods, Ref<JavaClass>());
|
||||||
|
|
||||||
Ref<JavaClass> java_class = memnew(JavaClass);
|
Ref<JavaClass> java_class = memnew(JavaClass);
|
||||||
@@ -1515,8 +1551,9 @@ Ref<JavaClass> JavaClassWrapper::_wrap(const String &p_class, bool p_allow_priva
|
|||||||
Vector<String> params;
|
Vector<String> params;
|
||||||
|
|
||||||
jint mods = env->CallIntMethod(obj, is_constructor ? Constructor_getModifiers : Method_getModifiers);
|
jint mods = env->CallIntMethod(obj, is_constructor ? Constructor_getModifiers : Method_getModifiers);
|
||||||
|
bool is_public = (mods & 0x0001) != 0; // java.lang.reflect.Modifier.PUBLIC
|
||||||
|
|
||||||
if (!(mods & 0x0001) && (is_constructor || !p_allow_private_methods_access)) {
|
if (!is_public && (is_constructor || !p_allow_non_public_methods_access)) {
|
||||||
env->DeleteLocalRef(obj);
|
env->DeleteLocalRef(obj);
|
||||||
continue; //not public bye
|
continue; //not public bye
|
||||||
}
|
}
|
||||||
@@ -1627,6 +1664,13 @@ Ref<JavaClass> JavaClassWrapper::_wrap(const String &p_class, bool p_allow_priva
|
|||||||
mi.method = env->GetMethodID(bclass, str_method.utf8().get_data(), signature.utf8().get_data());
|
mi.method = env->GetMethodID(bclass, str_method.utf8().get_data(), signature.utf8().get_data());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (env->ExceptionCheck()) {
|
||||||
|
// Exceptions may be thrown when trying to access hidden methods; write the exception to the logs and continue.
|
||||||
|
env->ExceptionDescribe();
|
||||||
|
env->ExceptionClear();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
ERR_CONTINUE(!mi.method);
|
ERR_CONTINUE(!mi.method);
|
||||||
|
|
||||||
java_class->methods[str_method].push_back(mi);
|
java_class->methods[str_method].push_back(mi);
|
||||||
@@ -1700,7 +1744,7 @@ JavaClassWrapper::JavaClassWrapper() {
|
|||||||
ERR_FAIL_NULL(env);
|
ERR_FAIL_NULL(env);
|
||||||
|
|
||||||
jclass bclass = jni_find_class(env, "java/lang/Class");
|
jclass bclass = jni_find_class(env, "java/lang/Class");
|
||||||
Class_getDeclaredConstructors = env->GetMethodID(bclass, "getDeclaredConstructors", "()[Ljava/lang/reflect/Constructor;");
|
Class_getConstructors = env->GetMethodID(bclass, "getConstructors", "()[Ljava/lang/reflect/Constructor;");
|
||||||
Class_getDeclaredMethods = env->GetMethodID(bclass, "getDeclaredMethods", "()[Ljava/lang/reflect/Method;");
|
Class_getDeclaredMethods = env->GetMethodID(bclass, "getDeclaredMethods", "()[Ljava/lang/reflect/Method;");
|
||||||
Class_getFields = env->GetMethodID(bclass, "getFields", "()[Ljava/lang/reflect/Field;");
|
Class_getFields = env->GetMethodID(bclass, "getFields", "()[Ljava/lang/reflect/Field;");
|
||||||
Class_getName = env->GetMethodID(bclass, "getName", "()Ljava/lang/String;");
|
Class_getName = env->GetMethodID(bclass, "getName", "()Ljava/lang/String;");
|
||||||
|
|||||||
Reference in New Issue
Block a user