Skip to content

Instantly share code, notes, and snippets.

@naveedmurtuza
Last active August 29, 2015 14:17
Show Gist options
  • Save naveedmurtuza/9e4d6ffdce0332534775 to your computer and use it in GitHub Desktop.
Save naveedmurtuza/9e4d6ffdce0332534775 to your computer and use it in GitHub Desktop.
Common helper functions for JNI
package com.generic.jni.byref;
/**
* class to facilitate passing of integer values by reference.
* @author Naveed
*/
public class IntegerByReference {
private int value;
public IntegerByReference(int value) {
this.value = value;
}
public IntegerByReference() {
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
}
/**
\file
\brief common functions for JNI
\author Naveed Quadri
\version 1.0
*/
#pragma once
#include <jni.h>
#define JNI_NO_CLASS_DEF "java/lang/NoClassDefFoundError"
#define JNI_NO_SUCH_METHOD "java/lang/NoSuchMethodError"
/**
\brief Throws Java exception
\param env Pointer to JNIEnv
\param name [in] fully qualified exception class name [ eg. java/lang/NoSuchMethodError ]
\param message [in] exception message
*/
void ThrowExceptionByClassName(JNIEnv *env, const char *name, const char *message)
{
jclass clazz = env->FindClass(name);
if (clazz != NULL) {
env->ThrowNew(clazz, message);
env->DeleteLocalRef(clazz);
}
}
/**
\brief Throws Java exception
\param env Pointer to JNIEnv
\param name [in] fully qualified exception class name [ eg. java/lang/NoSuchMethodError ]
\param message [in] exception message
*/
void CopyToCharPtr(JNIEnv *env, jstring string, char* dest, int size)
{
const char *nativeString = env->GetStringUTFChars(string, 0);
memcpy(dest, nativeString, size);
env->ReleaseStringUTFChars(string, nativeString);
}
/**
\brief convenience method to get the class and method
\param env Pointer to JNIEnv
\param clazzObj [int] class object
\param method_name [in] method name
\param sig [in] methid signature
\param clazz [out] exception message
\param mid [out] exception message
*/
bool GetClassAndMethodOrThrow(JNIEnv *env, jobject clazzObj,const char* method_name, const char* sig, jclass &clazz, jmethodID &mid)
{
clazz = env->GetObjectClass(clazzObj);
if (clazz == NULL)
{
ThrowExceptionByClassName(env, JNI_NO_CLASS_DEF, "");
return false;
}
mid = env->GetMethodID(clazz, method_name, sig);
if (mid == NULL)
{
ThrowExceptionByClassName(env, JNI_NO_SUCH_METHOD, method_name);
return false;
}
return true;
}
/**
\brief Gets jint from the clazzObj
\param env Pointer to JNIEnv
\param clazzObj [in] class object
\param method_name [in] method name
\param sig [in] method signature
\param value [out] jint value to returned
\return true if succeful, false otherwise
*/
bool GetIntValue(JNIEnv *env, jobject clazzObj, const char* name, const char* sig, jint &value)
{
jclass clazz;
jmethodID mid;
bool b = GetClassAndMethodOrThrow(env, clazzObj, name, sig, clazz, mid);
if (!b) return false;
value = env->CallIntMethod(clazzObj, mid);
return true;
}
/**
\brief Gets jlong from the clazzObj
\param env Pointer to JNIEnv
\param clazzObj [in] class object
\param method_name [in] method name
\param sig [in] method signature
\param value [out] jlong value to returned
\return true if succeful, false otherwise
*/
bool GetLongValue(JNIEnv *env, jobject clazzObj, const char* name, const char* sig,jlong &value)
{
jclass clazz;
jmethodID mid;
bool b = GetClassAndMethodOrThrow(env, clazzObj, name, sig, clazz, mid);
if (!b) return false;
value = env->CallLongMethod(clazzObj, mid);
return true;
}
/**
\brief Gets jbyte from the clazzObj
\param env Pointer to JNIEnv
\param clazzObj [in] class object
\param method_name [in] method name
\param sig [in] method signature
\param value [out] jbyte value to returned
\return true if succeful, false otherwise
*/
bool GetByteValue(JNIEnv *env, jobject clazzObj, const char* name, const char* sig, jbyte &value)
{
jclass clazz;
jmethodID mid;
bool b = GetClassAndMethodOrThrow(env, clazzObj, name, sig, clazz, mid);
if (!b) return false;
value = env->CallByteMethod(clazzObj, mid);
return true;
}
/**
\brief Gets jboolean from the clazzObj
\param env Pointer to JNIEnv
\param clazzObj [in] class object
\param method_name [in] method name
\param sig [in] method signature
\param value [out] jboolean value to returned
\return true if succeful, false otherwise
*/
bool GetBoolValue(JNIEnv *env, jobject clazzObj, const char* name, const char* sig, jboolean &value)
{
jclass clazz;
jmethodID mid;
bool b = GetClassAndMethodOrThrow(env, clazzObj, name, sig, clazz, mid);
if (!b) return false;
value = env->CallBooleanMethod(clazzObj, mid);
return true;
}
/**
\brief Gets jobject from the clazzObj
\param env Pointer to JNIEnv
\param clazzObj [in] class object
\param method_name [in] method name
\param sig [in] method signature
\param value [out] jobject value to returned
\return true if succeful, false otherwise
*/
bool GetObjectValue(JNIEnv *env, jobject clazzObj, const char* name, const char* sig, jobject &value)
{
jclass clazz;
jmethodID mid;
bool b = GetClassAndMethodOrThrow(env, clazzObj, name, sig, clazz, mid);
if (!b) return false;
value = env->CallObjectMethod(clazzObj, mid);
return true;
}
/**
\brief Gets jstring from the clazzObj
\param env Pointer to JNIEnv
\param clazzObj [in] class object
\param method_name [in] method name
\param sig [in] method signature
\param value [out] jstring value to returned
\return true if succeful, false otherwise
*/
bool GetString(JNIEnv *env, jobject clazzObj, const char* method_name, const char* sig, jstring &value)
{
jclass clazz;
jmethodID mid;
bool b = GetClassAndMethodOrThrow(env, clazzObj, method_name, sig, clazz, mid);
if (!b) return false;
jobject obj = env->CallObjectMethod(clazzObj, mid);
value = (jstring)obj;
return true;
}
/**
\brief Retrieves the jstring from the clazzObj and converts it to char*. Convenience method, same as calling ::GetString then ::CopyToCharPtr
\param env Pointer to JNIEnv
\param clazzObj [in] class object
\param method_name [in] method name
\param sig [in] method signature
\param dest [out] destination buffer
\param size [in] size of the destination buffer
\return true if succeful, false otherwise
*/
bool GetStringAsCharPtr(JNIEnv *env, jobject clazzObj, const char* name, const char* sig, char* dest,int size)
{
jstring str;
bool res = GetString(env, clazzObj, name, sig, str);
if (!res) return false;
CopyToCharPtr(env, str, dest, size);
return true;
}
template <class Type>
/**
\brief A generic setter method
\param env Pointer to JNIEnv
\param clazzObj [in] class object
\param method_name [in] method name
\param sig [in] method signature [ \see http://docs.oracle.com/javase/1.5.0/docs/guide/jni/spec/types.html ]
\param value the <Type> value to set
\return true if succeful, false otherwise
*/
bool SetValue(JNIEnv *env, jobject clazzObj, const char* method_name, const char* sig, Type value)
{
jclass clazz;
jmethodID mid;
bool res = GetClassAndMethodOrThrow(env, clazzObj, name, sig, clazz, mid);
if (!res) return false;
env->CallVoidMethod(clazzObj, mid, value);
return true;
}
package com.generic.jni.byref;
/**
* class to facilitate passing of long values by reference.
* @author Naveed
*/
public class LongByReference {
private long value;
public LongByReference() {
}
public LongByReference(long value) {
this.value = value;
}
public long getValue() {
return value;
}
public void setValue(long value) {
this.value = value;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment