diff --git a/examples/native_peer.cpp b/examples/native_peer.cpp index 78ec8e3..03ec0b6 100644 --- a/examples/native_peer.cpp +++ b/examples/native_peer.cpp @@ -12,7 +12,7 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) Calculator(const Calculator&) = delete; // noncopyable ~Calculator() { std::cout << "Native peer finalized" << std::endl; } - jni::jlong Add(jni::JNIEnv&, jni::jlong a, jni::jlong b) { return a + b; } + jni::jlong Add(jni::JNIEnv&, jni::jlong a, jni::jlong b) const { return a + b; } jni::jlong Subtract(jni::JNIEnv&, jni::jlong a, jni::jlong b) { return a - b; } }; diff --git a/include/jni/native_method.hpp b/include/jni/native_method.hpp index 192e301..dd06ac6 100644 --- a/include/jni/native_method.hpp +++ b/include/jni/native_method.hpp @@ -282,6 +282,31 @@ namespace jni } }; + template < class R, class P, class... Args, R (P::*method)(JNIEnv&, Args...) const> + class NativePeerMemberFunctionMethod< R (P::*)(JNIEnv&, Args...) const, method> + { + private: + const char* name; + + public: + NativePeerMemberFunctionMethod(const char* n) + : name(n) + {} + + template < class Peer, class TagType, class = std::enable_if_t< std::is_same::value > > + auto operator()(const Field& field) + { + auto wrapper = [field] (JNIEnv& env, Object& obj, Args... args) + { + auto ptr = reinterpret_cast(obj.Get(env, field)); + if (ptr) return (ptr->*method)(env, args...); + ThrowNew(env, jni::FindClass(env, "java/lang/IllegalStateException"), + "invalid native peer"); + }; + return MakeNativeMethod(name, wrapper); + } + }; + template < class M, M method> auto MakeNativePeerMethod(const char* name, std::enable_if_t< std::is_member_function_pointer::value >* = nullptr)