Created
September 28, 2012 11:14
-
-
Save OpenGamma-Blog/3799238 to your computer and use it in GitHub Desktop.
slf4j example 3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// global cache | |
extern JavaVM JVMCache; // global JVM pointer cache | |
static jclass wrappedClass = NULL; // holds the class that wraps the native code | |
static jclass slf4jLoggerClass = NULL; // holds the slf4j class | |
static jfieldID loggerFieldID = 0; // the ID of the Logger field "log" (this is a static reference set each time by the classloader) | |
static jmethodID loggerMethodID = 0; // the ID of the logger method (it's the ID obtained from the slf4j class (interface), the vtable is used to look up the particular method in the object which instantiated from this class) | |
// C code for the initialisation (we leave out exception handling for brevity) | |
#ifdef __cplusplus | |
extern "C" | |
#endif | |
/* | |
* This code is called on instantiation and is part of the static block of the wrapper | |
* Class: com_opengamma_maths_nativewrappers_OGNativeCodeWrapper | |
* Method: initialiseLogger | |
* Signature: ()V | |
*/ | |
JNIEXPORT void JNICALL Java_com_opengamma_maths_nativewrappers_OGNativeCodeWrapper_initialiseLogger(JNIEnv * env, jclass theClass) | |
{ | |
jint jStatus = 0; | |
JNIEnv *envPtr; // will hold env ptr | |
jclass tmpClass = NULL; //temporary class holder | |
// grab env ptr | |
jStatus=(*JVMcache)->AttachCurrentThread(JVMcache, (void **)&envPtr, NULL); | |
if(jStatus){ | |
//handle error | |
} | |
// find OGNativeCodeWrapper class | |
tmpClass = NULL; | |
tmpClass = (*envPtr)->FindClass(envPtr,"com/opengamma/maths/nativewrappers/OGNativeCodeWrapper"); // find class | |
if(tmpClass==NULL) { | |
//handle error | |
} | |
wrappedClass=NULL; // we set this to 0 so the global reference is 0'd out so we can catch fail if the classloader reloads | |
wrappedClass = (jclass)((*envPtr)->NewGlobalRef(envPtr,tmpClass)); | |
if(wrappedClass==NULL){ | |
//handle error | |
} | |
// find logger class | |
tmpClass = NULL; | |
tmpClass=(*envPtr)->FindClass(envPtr,"org/slf4j/Logger"); | |
if(tmpClass==NULL) { | |
//handle error | |
} | |
slf4jLoggerClass=NULL; // we set this to 0 so the global reference is 0'd out so we can catch fail if the classloader reloads | |
slf4jLoggerClass = (jclass)((*envPtr)->NewGlobalRef(envPtr,tmpClass)); | |
if(slf4jLoggerClass==NULL) { | |
//handle error | |
} | |
loggerFieldID = 0; // we set this to 0 so the global reference is 0'd out so we can catch fail if the classloader reloads | |
loggerFieldID = (*envPtr)->GetStaticFieldID(envPtr, wrappedClass, "log", "Lorg/slf4j/Logger;"); | |
if (loggerFieldID == 0) { | |
//handle error | |
} | |
loggerMethodID = 0; // we set this to 0 so the global reference is 0'd out so we can catch fail if the classloader reloads | |
loggerMethodID = (*envPtr)->GetMethodID(envPtr, slf4jLoggerClass, "warn", "(Ljava/lang/String;)V"); | |
if (loggerMethodID == 0) { | |
//handle error | |
} | |
} | |
// implement fortran f_log_buffered | |
#define F_LOG_BUFFERED_F77 F77_FUNC(f_log_buffered,F_LOG_BUFFERED) | |
#ifdef __cplusplus | |
extern "C" | |
#endif | |
void F_LOG_BUFFERED_F77(char *, int*); | |
// by virtue of static initialisation the global pointers to the static classes, ids and methods will be set before this is called | |
#ifdef __cplusplus | |
extern "C" | |
#endif | |
void F_LOG_BUFFERED_F77(char * c, int * length) | |
{ | |
// points to an object instantiated from a slf4j logger class (it's an interface, who knows what the object will be!) | |
jobject theLogger = NULL; | |
jint jStatus = 0; // status for jvm grabbing calls | |
char * messageBuffer = NULL; // buffer for the message before its UTF8ilised | |
JNIEnv *envPtr; // will hold env ptr | |
jstring javaMessage = NULL; // will hold the hava message for slf4j | |
// grab env ptr | |
jStatus=(*JVMcache)->AttachCurrentThread(JVMcache, (void **)&envPtr, NULL); | |
if(jStatus){ | |
//handle error | |
} | |
// all we know is that the logger implements a slf4j interface so we have to get a pointer to the instantiated version | |
theLogger = (*envPtr)->GetStaticObjectField(envPtr, wrappedClass, loggerFieldID); | |
if(theLogger==NULL){ | |
//handle error | |
} | |
// create a buffer for the message | |
messageBuffer = (char *) malloc(*length+1); | |
if(messageBuffer == NULL) { | |
//handle error | |
} | |
// copy in the message based on the length given by Fortran len(log_message) | |
memcpy(messageBuffer,log_message,(size_t)*length); | |
// nul terminate | |
*(messageBuffer+*length)='\0'; | |
// knock out high bits/bits out of UTF8 land, worst case things'll just look a bit funny. | |
size_t i; | |
for(i=0;i<*length;i++) | |
{ | |
*(messageBuffer+i)&=0x7f; | |
} | |
// create a string from modified UTF8 | |
javaMessage = (*envPtr)->NewStringUTF(envPtr,messageBuffer); | |
if(javaMessage == NULL) { | |
//handle error | |
} | |
// call the method | |
(*envPtr)->CallVoidMethod(envPtr, theLogger, loggerMethodID, javaMessage); // we've no idea if this worked, it returns void | |
// delete reference to the java string as it's been shoved in the log | |
(*envPtr)->DeleteLocalRef(envPtr,javaMessage);// we've no idea if this worked, it returns void | |
// free the message buffer | |
free(messageBuffer); | |
return; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment