28package com.jogamp.gluegen;
30import java.io.IOException;
53 public void emitHeader(
final String packageName,
final String className,
final List<String> customCode) {
54 emitln(
"#include <jni.h>");
55 emitln(
"#include <stdlib.h>");
56 emitln(
"#include <string.h>");
57 emitln(
"#include <assert.h>");
58 emitln(
"#include <stddef.h>");
62 emitln(
"static jobject JVMUtil_NewDirectByteBufferCopy(JNIEnv *env, jclass clazzBuffers, void * source_address, size_t capacity); /* forward decl. */");
65 boolean addNewDirectByteBufferCopyUnitCode =
false;
66 for (
final String code : customCode) {
68 addNewDirectByteBufferCopyUnitCode = addNewDirectByteBufferCopyUnitCode || code.contains(
"JVMUtil_NewDirectByteBufferCopy");
71 if( addNewDirectByteBufferCopyUnitCode ) {
90 "static const char * nameCopyNativeToDirectByteBuffer = \"copyNativeToDirectByteBuffer\";\n"+
91 "static const char * nameCopyNativeToDirectByteBufferSignature = \"(JJ)Ljava/nio/ByteBuffer;\";\n"+
93 "static jobject JVMUtil_NewDirectByteBufferCopy(JNIEnv *env, jclass clazzBuffers, void * source_address, size_t capacity) {\n"+
94 " jmethodID cstrBuffersNew = (*env)->GetStaticMethodID(env, clazzBuffers, nameCopyNativeToDirectByteBuffer, nameCopyNativeToDirectByteBufferSignature);\n"+
95 " if(NULL==cstrBuffersNew) {\n"+
96 " fprintf(stderr, \"Can't get method Buffers.%s(%s)\\n\", nameCopyNativeToDirectByteBuffer, nameCopyNativeToDirectByteBufferSignature);\n"+
97 " (*env)->FatalError(env, nameCopyNativeToDirectByteBuffer);\n"+
98 " return JNI_FALSE;\n"+
100 " jobject jbyteBuffer = (*env)->CallStaticObjectMethod(env, clazzBuffers, cstrBuffersNew, (jlong)(intptr_t)source_address, (jlong)capacity);\n"+
101 " if( (*env)->ExceptionCheck(env) ) {\n"+
102 " (*env)->ExceptionDescribe(env);\n"+
103 " (*env)->ExceptionClear(env);\n"+
104 " (*env)->FatalError(env, \"Exception occurred\");\n"+
107 " return jbyteBuffer;\n"+
119 return "JavaVM* JVMUtil_GetJavaVM();\n"+
120 "JNIEnv* JVMUtil_GetJNIEnv(int asDaemon, int* jvmAttached);\n"+
121 "void JVMUtil_ReleaseJNIEnv(JNIEnv* env, int detachJVM);\n";
138 final String jvmHandleName = libraryBasename+
"_jvmHandle";
139 final StringBuilder sb =
new StringBuilder();
140 sb.append(
"static JavaVM *").append(jvmHandleName).append(
" = NULL;\n");
142 sb.append(
"JavaVM* JVMUtil_GetJavaVM() {\n");
143 sb.append(
" return ").append(jvmHandleName).append(
";\n");
145 sb.append(
"JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *initVM, void *reserved) {\n");
146 sb.append(
" (void)reserved;\n");
147 sb.append(
" ").append(jvmHandleName).append(
" = initVM;\n");
149 sb.append(
" fprintf(stderr, \"ON_LOAD_0 lib '").append(libraryBasename).append(
"'\\n\");\n");
151 sb.append(
" return JNI_VERSION_1_8;\n");
153 sb.append(
"JNIEXPORT jint JNICALL JNI_OnLoad_").append(libraryBasename).append(
"(JavaVM *initVM, void *reserved) {\n");
154 sb.append(
" (void)reserved;\n");
155 sb.append(
" ").append(jvmHandleName).append(
" = initVM;\n");
157 sb.append(
" fprintf(stderr, \"ON_LOAD_1 lib '").append(libraryBasename).append(
"'\\n\");\n");
159 sb.append(
" return JNI_VERSION_1_8;\n");
162 sb.append(
"JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved) {\n");
163 sb.append(
" (void)vm;\n");
164 sb.append(
" (void)reserved;\n");
165 sb.append(
" ").append(jvmHandleName).append(
" = NULL;\n");
167 sb.append(
" fprintf(stderr, \"ON_UNLOAD_0 lib '").append(libraryBasename).append(
"'\\n\");\n");
171 sb.append(
"JNIEXPORT void JNICALL JNI_OnUnload_").append(libraryBasename).append(
"(JavaVM *vm, void *reserved) {\n");
172 sb.append(
" (void)vm;\n");
173 sb.append(
" (void)reserved;\n");
174 sb.append(
" ").append(jvmHandleName).append(
" = NULL;\n");
176 sb.append(
" fprintf(stderr, \"ON_UNLOAD_1 lib '").append(libraryBasename).append(
"'\\n\");\n");
180 sb.append(
"JNIEnv* JVMUtil_GetJNIEnv(int asDaemon, int* jvmAttached) {\n");
181 sb.append(
" JNIEnv* curEnv = NULL;\n");
182 sb.append(
" JNIEnv* newEnv = NULL;\n");
183 sb.append(
" int envRes;\n");
185 sb.append(
" if( NULL != jvmAttached ) {\n");
186 sb.append(
" *jvmAttached = 0;\n");
188 sb.append(
" if(NULL==").append(jvmHandleName).append(
") {\n");
189 sb.append(
" fprintf(stderr, \"JVMUtil_GetJNIEnv(").append(libraryBasename).append(
"): No JavaVM handle registered.\\n\");\n");
190 sb.append(
" return NULL;\n");
193 sb.append(
" // retrieve this thread's JNIEnv curEnv - or detect it's detached\n");
194 sb.append(
" envRes = (*").append(jvmHandleName).append(
")->GetEnv(").append(jvmHandleName).append(
", (void **) &curEnv, JNI_VERSION_1_8) ;\n");
195 sb.append(
" if( JNI_EDETACHED == envRes ) {\n");
196 sb.append(
" // detached thread - attach to JVM as daemon, w/o need to be detached!\n");
197 sb.append(
" if( asDaemon ) {\n");
198 sb.append(
" envRes = (*").append(jvmHandleName).append(
")->AttachCurrentThreadAsDaemon(").append(jvmHandleName).append(
", (void**) &newEnv, NULL);\n");
199 sb.append(
" } else {\n");
200 sb.append(
" envRes = (*").append(jvmHandleName).append(
")->AttachCurrentThread(").append(jvmHandleName).append(
", (void**) &newEnv, NULL);\n");
202 sb.append(
" if( JNI_OK != envRes ) {\n");
203 sb.append(
" fprintf(stderr, \"JVMUtil_GetJNIEnv(").append(libraryBasename).append(
"): Can't attach thread: %d\\n\", envRes);\n");
204 sb.append(
" return NULL;\n");
206 sb.append(
" curEnv = newEnv;\n");
207 sb.append(
" } else if( JNI_OK != envRes ) {\n");
208 sb.append(
" // oops ..\n");
209 sb.append(
" fprintf(stderr, \"JVMUtil_GetJNIEnv(").append(libraryBasename).append(
"): Can't GetEnv: %d\\n\", envRes);\n");
210 sb.append(
" return NULL;\n");
212 sb.append(
" if (curEnv==NULL) {\n");
213 sb.append(
" fprintf(stderr, \"JVMUtil_GetJNIEnv(").append(libraryBasename).append(
"): env is NULL\\n\");\n");
214 sb.append(
" return NULL;\n");
216 sb.append(
" if( NULL != jvmAttached ) {\n");
217 sb.append(
" *jvmAttached = NULL != newEnv;\n");
220 sb.append(
" fprintf(stderr, \"JVMUtil_GetJNIEnv(").append(libraryBasename).append(
", asDaemon %d): jvmAttached %d -> env %p\\n.\", asDaemon, (NULL != newEnv), curEnv);\n");
222 sb.append(
" return curEnv;\n");
225 sb.append(
"void JVMUtil_ReleaseJNIEnv(JNIEnv* env, int detachJVM) {\n");
226 sb.append(
" if(NULL==").append(jvmHandleName).append(
") {\n");
227 sb.append(
" fprintf(stderr, \"JVMUtil_ReleaseJNIEnv(").append(libraryBasename).append(
"): No JavaVM handle registered.\\n\");\n");
228 sb.append(
" return;\n");
230 sb.append(
" if( detachJVM ) {\n");
231 sb.append(
" jint res = (*").append(jvmHandleName).append(
")->DetachCurrentThread(").append(jvmHandleName).append(
") ;\n");
232 sb.append(
" if( 0 != res ) {\n");
233 sb.append(
" fprintf(stderr, \"JVMUtil_ReleaseJNIEnv(").append(libraryBasename).append(
", env %p): Failed with res %d\\n.\", env, res);\n");
234 sb.append(
" return;\n");
237 sb.append(
" fprintf(stderr, \"JVMUtil_ReleaseJNIEnv(").append(libraryBasename).append(
", env %p) -> res %d\\n.\", env, res);\n");
242 return sb.toString();
C code unit (a generated C source file), covering multiple FunctionEmitter allowing to unify output,...
void emitJNIEnvDecl()
Emits getJNIEnvDecl().
final String cUnitName
base c-unit name with suffix.
static final String getJNIOnLoadJNIEnvCode(final String libraryBasename)
Returns native JNI code JNI_OnLoad(..) used for dynamic libraries, JNI_OnLoad_{libraryBasename}(....
CCodeUnit(final String filename, final String cUnitName, final Object generator)
void emitJNIOnLoadJNIEnvCode(final String libraryBasename)
Emits getJNIOnLoadJNIEnvCode(String).
void emitHeader(final String packageName, final String className, final List< String > customCode)
static final String getJNIEnvDecl()
Returns native JNI declarations for JVMUtil_GetJavaVM(), JVMUtil_GetJNIEnv(..) and JVMUtil_ReleaseJNI...
static final String NewDirectByteBufferCopyUnitCode
static void emitAutogeneratedWarning(final PrintWriter w, final Object generator, final String customLine)
General code unit (a generated C or Java source file), covering multiple FunctionEmitter allowing to ...
boolean addTailCode(final String c)
Add a tail code to this unit.
Glue code generator for C functions and data structures.