1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
|
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.example.jni_generator;
// This class serves as a reference test for the bindings generator, and as example documentation
// for how to use the jni generator.
// The C++ counter-part is sample_for_tests.cc.
// jni_generator.gyp has a jni_generator_tests target that will:
// * Generate a header file for the JNI bindings based on this file.
// * Compile sample_for_tests.cc using the generated header file.
// * link a native executable to prove the generated header + cc file are self-contained.
// All comments are informational only, and are ignored by the jni generator.
class SampleForTests {
// Classes can store their C++ pointer counter part as an int that is normally initialized by
// calling out a nativeInit() function.
int nativePtr;
// You can define methods and attributes on the java class just like any other.
// Methods without the @CalledByNative annotation won't be exposed to JNI.
public SampleForTests() {
}
public void startExample() {
// Calls native code and holds a pointer to the C++ class.
nativePtr = nativeInit("myParam");
}
public void doStuff() {
// This will call CPPClass::Method() using nativePtr as a pointer to the object. This must be
// done to:
// * avoid leaks.
// * using finalizers are not allowed to destroy the cpp class.
nativeMethod(nativePtr);
}
public void finishExample() {
// We're done, so let's destroy nativePtr object.
nativeDestroy(nativePtr);
}
// -----------------------------------------------------------------------------------------------
// The following methods demonstrate exporting Java methods for invocation from C++ code.
// Java functions are mapping into C global functions by prefixing the method name with
// "Java_<Class>_"
// This is triggered by the @CalledByNative annotation; the methods may be named as you wish.
// Exported to C++ as:
// Java_Example_javaMethod(JNIEnv* env, jobject obj, jint foo, jint bar)
// Typically the C++ code would have obtained the jobject via the Init() call described above.
@CalledByNative
public int javaMethod(int foo,
int bar) {
return 0;
}
// Exported to C++ as Java_Example_staticJavaMethod(JNIEnv* env)
// Note no jobject argument, as it is static.
@CalledByNative
public static boolean staticJavaMethod() {
return true;
}
// No prefix, so this method is package private. It will still be exported.
@CalledByNative
void packagePrivateJavaMethod() {}
// Note the "Unchecked" suffix. By default, @CalledByNative will always generate bindings that
// call CheckException(). With "@CalledByNativeUnchecked", the client C++ code is responsible to
// call ClearException() and act as appropriate.
// See more details at the "@CalledByNativeUnchecked" annotation.
@CalledByNativeUnchecked
void methodThatThrowsException() throws Exception {}
//------------------------------------------------------------------------------------------------
// Java fields which are accessed from C++ code must be annotated with @AccessedByNative to
// prevent them being eliminated when unreferenced code is stripped.
@AccessedByNative
private int javaField;
//------------------------------------------------------------------------------------------------
// The following methods demonstrate declaring methods to call into C++ from Java.
// The generator detects the "native" and "static" keywords, the type and name of the first
// parameter, and the "native" prefix to the function name to determine the C++ function
// signatures. Besides these constraints the methods can be freely named.
// This declares a C++ function which the application code must implement:
// static jint Init(JNIEnv* env, jobject obj);
// The jobject parameter refers back to this java side object instance.
// The implementation must return the pointer to the C++ object cast to jint.
// The caller of this method should store it, and supply it as a the nativeCPPClass param to
// subsequent native method calls (see the methods below that take an "int native..." as first
// param).
private native int nativeInit();
// This defines a function binding to the associated C++ class member function. The name is
// derived from |nativeDestroy| and |nativeCPPClass| to arrive at CPPClass::Destroy() (i.e. native
// prefixes stripped).
// The |nativeCPPClass| is automatically cast to type CPPClass* in order to obtain the object on
// which to invoke the member function.
private native void nativeDestroy(int nativeCPPClass);
// This declares a C++ function which the application code must implement:
// static jdouble GetDoubleFunction(JNIEnv* env, jobject obj);
// The jobject parameter refers back to this java side object instance.
private native double nativeGetDoubleFunction();
// Similar to nativeGetDoubleFunction(), but here the C++ side will receive a jclass rather than
// jobject param, as the function is declared static.
private static native float nativeGetFloatFunction();
// This function takes a non-POD datatype. We have a list mapping them to their full classpath in
// jni_generator.py JavaParamToJni. If you require a new datatype, make sure you add to that
// function.
private native void nativeSetNonPODDatatype(Rect rect);
// This declares a C++ function which the application code must implement:
// static ScopedJavaLocalRef<jobject> GetNonPODDatatype(JNIEnv* env, jobject obj);
// The jobject parameter refers back to this java side object instance.
// Note that it returns a ScopedJavaLocalRef<jobject> so that you don' have to worry about
// deleting the JNI local reference. This is similar with Strings and arrays.
private native Object nativeGetNonPODDatatype();
// Similar to nativeDestroy above, this will cast nativeCPPClass into pointer of CPPClass type and
// call its Method member function.
private native int nativeMethod(int nativeCPPClass);
// Similar to nativeMethod above, but here the C++ fully qualified class name is taken from the
// comment rather than parameter name, which can thus be chosen freely.
private native double nativeMethodOtherP0(int nativeCPPClass /* cpp_namespace::CPPClass */);
// An inner class has some special attributes for annotation.
class InnerClass {
@CalledByNative("InnerClass")
public float JavaInnerMethod() {
}
@CalledByNative("InnerClass")
public static void javaInnerFunction() {
}
@NativeCall("InnerClass")
private static native int nativeInnerFunction();
@NativeCall("InnerClass")
private static native String nativeInnerMethod(int nativeCPPClass);
}
}
|