/
jni_helpers.c
137 lines (104 loc) · 3.73 KB
/
jni_helpers.c
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
/* ______ ___ ___
* /\ _ \ /\_ \ /\_ \
* \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
* \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
* \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
* \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
* \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
* /\____/
* \_/__/
*
* Android jni helpers
*
* By Thomas Fjellstrom.
*
*/
#include "allegro5/allegro.h"
#include "allegro5/internal/aintern_android.h"
#include <jni.h>
#include <stdarg.h>
ALLEGRO_DEBUG_CHANNEL("jni")
#define VERBOSE_DEBUG(a, ...) (void)0
/* jni helpers */
void __jni_checkException(JNIEnv *env, const char *file, const char *func, int line)
{
jthrowable exc;
exc = (*env)->ExceptionOccurred(env);
if (exc) {
ALLEGRO_DEBUG("GOT AN EXCEPTION @ %s:%i %s", file, line, func);
/* We don't do much with the exception, except that
we print a debug message for it, clear it, and
throw a new exception. */
(*env)->ExceptionDescribe(env);
(*env)->ExceptionClear(env);
(*env)->FatalError(env, "EXCEPTION");
//(*env)->ThrowNew(env, system_data.illegal_argument_exception_class, "thrown from C code");
}
}
jobject _jni_callObjectMethod(JNIEnv *env, jobject object,
const char *name, const char *sig)
{
VERBOSE_DEBUG("%s (%s)", name, sig);
jclass class_id = _jni_call(env, jclass, GetObjectClass, object);
jmethodID method_id = _jni_call(env, jmethodID, GetMethodID, class_id, name, sig);
jobject ret = _jni_call(env, jobject, CallObjectMethod, object, method_id);
_jni_callv(env, DeleteLocalRef, class_id);
return ret;
}
jobject _jni_callObjectMethodV(JNIEnv *env, jobject object,
const char *name, const char *sig, ...)
{
va_list ap;
VERBOSE_DEBUG("%s (%s)", name, sig);
jclass class_id = _jni_call(env, jclass, GetObjectClass, object);
jmethodID method_id = _jni_call(env, jmethodID, GetMethodID, class_id, name, sig);
va_start(ap, sig);
jobject ret = _jni_call(env, jobject, CallObjectMethodV, object, method_id, ap);
va_end(ap);
_jni_callv(env, DeleteLocalRef, class_id);
VERBOSE_DEBUG("callObjectMethodV end");
return ret;
}
ALLEGRO_USTR *_jni_getString(JNIEnv *env, jstring str_obj)
{
VERBOSE_DEBUG("GetStringUTFLength");
jsize len = _jni_call(env, jsize, GetStringUTFLength, str_obj);
const char *str = _jni_call(env, const char *, GetStringUTFChars, str_obj, NULL);
VERBOSE_DEBUG("al_ustr_new_from_buffer");
ALLEGRO_USTR *ustr = al_ustr_new_from_buffer(str, len);
_jni_callv(env, ReleaseStringUTFChars, str_obj, str);
return ustr;
}
ALLEGRO_USTR *_jni_callStringMethod(JNIEnv *env, jobject obj,
const char *name, const char *sig)
{
jstring str_obj = (jstring)_jni_callObjectMethod(env, obj, name, sig);
ALLEGRO_USTR *ustr = _jni_getString(env, str_obj);
_jni_callv(env, DeleteLocalRef, str_obj);
return ustr;
}
jobject _jni_callStaticObjectMethodV(JNIEnv *env, jclass cls,
const char *name, const char *sig, ...)
{
jmethodID mid;
jobject ret;
va_list ap;
mid = _jni_call(env, jmethodID, GetStaticMethodID, cls, name, sig);
va_start(ap, sig);
ret = _jni_call(env, jobject, CallStaticObjectMethodV, cls, mid, ap);
va_end(ap);
return ret;
}
jint _jni_callStaticIntMethodV(JNIEnv *env, jclass cls,
const char *name, const char *sig, ...)
{
jmethodID mid;
jint ret;
va_list ap;
mid = _jni_call(env, jmethodID, GetStaticMethodID, cls, name, sig);
va_start(ap, sig);
ret = _jni_call(env, jint, CallStaticIntMethodV, cls, mid, ap);
va_end(ap);
return ret;
}
/* vim: set sts=3 sw=3 et: */