|
| 1 | +#include "binding.hpp" |
| 2 | + |
| 3 | +namespace java { namespace lang { struct Object; } } |
| 4 | +namespace java { namespace lang { struct String; } } |
| 5 | + |
| 6 | +namespace jni { |
| 7 | + |
| 8 | +template <> struct Name<java::lang::Object> { |
| 9 | + using Tag = ObjectTag; |
| 10 | +}; |
| 11 | + |
| 12 | +template <> struct Name<java::lang::String> { |
| 13 | + using Tag = StringTag; |
| 14 | +}; |
| 15 | + |
| 16 | +} // namespace jni |
| 17 | + |
| 18 | + |
| 19 | +namespace java { |
| 20 | +namespace lang { |
| 21 | + |
| 22 | +struct Object : jni::Binding<Object> { |
| 23 | + using Binding::Binding; |
| 24 | +}; |
| 25 | + |
| 26 | +struct String : jni::Binding<String> { |
| 27 | + using Binding::Binding; |
| 28 | + |
| 29 | + // Java methods |
| 30 | + |
| 31 | + jni::jint length(jni::JNIEnv& env) { |
| 32 | + static const auto method = jni_GetMethod<jni::jint()>(env, "length"); |
| 33 | + return self.Call(env, method); |
| 34 | + } |
| 35 | +}; |
| 36 | + |
| 37 | +} // namespace lang |
| 38 | +} // namespace java |
| 39 | + |
| 40 | + |
| 41 | + |
| 42 | +struct HighLevelBinding; |
| 43 | + |
| 44 | +namespace jni { |
| 45 | +template <> struct Name<HighLevelBinding>::Tag { |
| 46 | + static constexpr auto Name() { return "HighLevelBinding"; } |
| 47 | +}; |
| 48 | +} // namespace jni |
| 49 | + |
| 50 | +struct HighLevelBinding : jni::Binding<HighLevelBinding> { |
| 51 | + using Binding::Binding; |
| 52 | + |
| 53 | + HighLevelBinding(jni::JNIEnv& env) : Binding(jni_New<>(env)) {} |
| 54 | + |
| 55 | + // Java methods |
| 56 | + jni::jint quadruple(jni::JNIEnv& env, jni::jint num) { |
| 57 | + // Call Java method |
| 58 | + static const auto method = jni_GetMethod<jni::jint(jni::jint)>(env, "quadruple"); |
| 59 | + return self.Call(env, method, num); |
| 60 | + } |
| 61 | + |
| 62 | + // Native methods |
| 63 | + void greet(jni::JNIEnv&, java::lang::String args); |
| 64 | + void greet(jni::JNIEnv&, jni::jint args); |
| 65 | + static void greet(jni::JNIEnv&, jni::jdouble args); |
| 66 | + |
| 67 | + |
| 68 | + static void jni_Register(jni::JNIEnv& env) { |
| 69 | + jni::RegisterNatives(env, jni_Class(env), |
| 70 | + jni_Bind<void(java::lang::String)>::Method<&HighLevelBinding::greet>("greet"), |
| 71 | + jni_Bind<void(jni::jint)>::Method<&HighLevelBinding::greet>("greet"), |
| 72 | + jni_Bind<void(jni::jdouble)>::StaticMethod<&HighLevelBinding::greet>("greet") |
| 73 | + ); |
| 74 | + } |
| 75 | +}; |
| 76 | + |
| 77 | + |
| 78 | +void HighLevelBinding::greet(jni::JNIEnv& env, java::lang::String args) { |
| 79 | + const auto test = jni::Make<std::string>(env, args); |
| 80 | + fprintf(stderr, "greet '%s' (length %d)\n", test.c_str(), args.length(env)); |
| 81 | +} |
| 82 | + |
| 83 | +void HighLevelBinding::greet(jni::JNIEnv& env, jni::jint args) { |
| 84 | + fprintf(stderr, "greet %d\n", quadruple(env, args)); |
| 85 | +} |
| 86 | + |
| 87 | +void HighLevelBinding::greet(jni::JNIEnv&, jni::jdouble args) { |
| 88 | + fprintf(stderr, "greet static %f\n", args); |
| 89 | +} |
| 90 | + |
| 91 | + |
| 92 | + |
| 93 | +extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) { |
| 94 | + jni::JNIEnv& env{ jni::GetEnv(*vm) }; |
| 95 | + try { |
| 96 | + java::lang::Object::jni_Register(env); |
| 97 | + java::lang::String::jni_Register(env); |
| 98 | + HighLevelBinding::jni_Register(env); |
| 99 | + } catch (const jni::PendingJavaException&) { |
| 100 | + jni::ExceptionDescribe(env); |
| 101 | + } |
| 102 | + return jni::Unwrap(jni::jni_version_1_2); |
| 103 | +} |
0 commit comments