Raw Native Interface Functions
This reference describes the functions defined in the native.h and nativcom.h header files (unless noted, prototype is found in native.h).
These functions are used by the Raw Native Interface defined by the Microsoft® Virtual Machine for efficiently interfacing Java code with native code.
To learn how to use the API, see the overview information in Raw Native Interface.
The following functions are defined in native.h and nativcom.h:
__cdecl AddModuleResourceClassSource(HMODULE hMod, DWORD dwResID);
Notifies the virtual machine of a WIN32 resource containing class files. This resource must be in the format created by JExeGen. When classes are being loaded, the resource is searched for classes as if it were a directory on the classpath.
BOOL __cdecl AddPathClassSource(const char *path, BOOL fAppend);
Adds a path to the virtual machine's internal class path.
HObject* __cdecl ArrayAlloc(int type, int cItems);
Creates an array of primitive type objects.
Return Value:
Returns an allocated object array.
Parameter | Description |
type
| Primitive data type as defined in native.h. The following types are supported:
T_BOOLEAN | A Boolean object.
| T_BYTE | A Byte object.
| T_CHAR | A Character object.
| T_CLASS | A Class object.
| T_DOUBLE | A Double object.
| T_FLOAT | A Float object.
| T_INT | An Integer object.
| T_LONG | A Long object
| T_SHORT | A Short object.
|
|
cItems
| Number of items in the array.
|
void __cdecl ArrayCopy(HObject *srch, long src_pos, HObject *dsth,
long dst_pos, long length);
Copies an array using the Java System.ArrayCopy method.
Parameter | Description |
srch
| Source object.
|
src_pos
| Starting position in the source object array to copy.
|
dsth
| Destination object.
|
dst_pos
| Position in the destination object array to copy to.
|
length
| Number of objects in the array to copy.
|
ClassClass * __cdecl c2jhook_getexposingclass(C2JMethodHookInfo *phookinfo);
Returns the class defining the interface method. This is the class containing the MCCustomMethod descriptor.
WORD __cdecl c2jhook_getsizeofuserdata(C2JMethodHookInfo *phookinfo);
Gets size of user data in the MCCustomMethod descriptor.
LPVOID __cdecl c2jhook_getuserdata(C2JMethodHookInfo *phookinfo);
Gets writable pointer to the user data in the MCCustomMethod descriptor.
int __cdecl Class_CopyConstantPoolItem(ClassClass *cls, unsigned index, BYTE *pbuf, int size, DWORD flags, BYTE *ptype);
Copies a constant pool item. For Utf8 items, the buffer size is not the number of characters, and the copied string will be null-terminated; size includes the null-terminator. For ClassRef, FieldRef, etc., the buffer is filled in with a struct ptr.
CP Type | Buffer Contents |
CP_Utf8
| Null-terminated string.
|
CP_Unicode
| (error)CP_Integer
| longCP_Float
| floatCP_Long
| __int64CP_Double
| doubleCP_Class
| ClassClass*CP_String
| HObject*CP_FieldRef
| fieldblock*CP_MethodRef
| methodblock*CP_IntfMethod
| methodblock*CP_NameAndType
| (error)
| | | | | | | | | | |
Parameter | Description |
size
| The size of pbuf in bytes. May be NULL to obtain only the size/type.
|
ptype
| Type of the pool item. Returns the number of bytes copied or needed, or -1 if failed. Filled in on output.flags
| If the constant pool item has not yet been used, force its referent to be loaded or looked up. With this flag set, the method may cause garbage collection.
| |
unsigned __cdecl Class_GetConstantPoolCount(ClassClass *cls);
Gets the constant pool count.
int __cdecl Class_GetAttributes(ClassClass *cls);
Retrieves a combination of the ACC_XXX flags for a class as they appear in the Java class file.
Return Value:
Returns attributes flags.
Parameter | Description |
cls
| Address of the class object.
|
Remarks:
The following attributes are defined for use in a Java class file and can be retrieved using this function:
Flag | Value
|
ACC_PUBLIC | 0x0001
|
ACC_PRIVATE | 0x0002
|
ACC_PROTECTED | 0x0004
|
ACC_STATIC | 0x0008
|
ACC_FINAL | 0x0010
|
ACC_SYNCH | 0x0020
|
ACC_SUPER | 0x0020
|
ACC_THREADSAFE | 0x0040
|
ACC_VOLATILE | 0x0040
|
ACC_TRANSIENT | 0x0080
|
ACC_NATIVE | 0x0100
|
ACC_INTERFACE | 0x0200
|
ACC_ABSTRACT | 0x0400
|
struct fieldblock * __cdecl Class_GetField(ClassClass *cls, const char *name);
Retrieves a handle to a field explicitly specified by name. This handle is needed to get any further information about the field.
Return Value:
Returns a pointer to the field block.
Parameter | Description |
cls
| Address of the class object. Use FindClass to determine.
|
name
| Name of the field in the class.
|
struct fieldblock * __cdecl Class_GetFieldByIndex(ClassClass *cls, unsigned index);
Retrieves a handle to a field specified by index.
Return Value:
Returns a field block pointer.
Parameter | Description |
cls
| Address of the class object. Use FindClass to determine.
|
index
| Index value of the field in the class. The index must be between 0 and the field count (returned from Class_GetFieldCount) minus 1, inclusive.
|
unsigned __cdecl Class_GetFieldCount(ClassClass *cls);
Retrieves the total number of fields in the class, including super and static fields.
Return Value:
Returns the number of fields.
Parameter | Description |
cls
| Address of the class object. Use FindClass to determine.
|
Remarks:
This function is intended to be used with Class_GetFieldByIndex to
enumerate fields on a class.
ClassClass * __cdecl Class_GetInterface(ClassClass *cls, unsigned index);
Retrieves an interface specified by index.
Return Value:
Returns a pointer to a class interface object.
Parameter | Description |
cls
| Address of the class object. Use FindClass to determine.
|
index
| Index value of the interface in the class. The index must be between 0 and the interface count (returned from Class_GetInterfaceCount) minus 1, inclusive.
|
unsigned __cdecl Class_GetInterfaceCount(ClassClass *cls);
Retrieves the total number of interfaces implemented by the class.
Return Value:
Returns the number of interfaces.
Parameter | Description |
cls
| Address of the class object. Use FindClass to determine.
|
struct methodblock* __cdecl Class_GetMethod(ClassClass *cls, const char *name, const char *signature);
Retrieves a handle to a method explicitly specified by name. This handle is needed to get any further information about the method.
Return Value:
Returns a handle to a method in the given class specified by name and signature.
Parameter | Description |
cls
| Address of the class object. Use FindClass to determine.
|
name
| Name of the method in the class.
|
struct methodblock* __cdecl Class_GetMethodByIndex(ClassClass *cls, unsigned index);
Retrieves a handle to a method specified by index.
Return Value:
Returns a method block pointer.
Parameter | Description |
cls
| Address of the class object. Use FindClass to determine.
|
index
| Index value of the method in the class. The index must be between 0 and the method count (returned from Class_GetMethodCount) minus 1, inclusive.
|
unsigned __cdecl Class_GetMethodCount(ClassClass *cls);
Retrieves the total number of methods in the class, including non-static super methods.
Return Value:
Returns the number of methods.
Parameter | Description |
cls
| Address of the class object. Use FindClass to determine.
|
Remarks:
This function is intended for use with Class_GetMethodByIndex to enumerate methods in a class.
This function returns the total count of all members, not just the count of those declared in the class specified. To find declared members, you must enumerate methods and call Member_GetClass on each to determine where the method is implemented.
const char * __cdecl Class_GetName(ClassClass *cls);
Retrieves the class name.
Return Value:
Returns class name.
Parameter | Description |
cls
| Address of the class object.
|
ClassClass * __cdecl Class_GetSuper(ClassClass *cls);
Retrieves the superclass.
Return Value:
Returns the superclass.
Parameter | Description |
cls
| Address of the class object.
|
HObject* __cdecl ClassArrayAlloc(int type, int cItems, char *szSig);
Creates an array of objects.
Return Value:
Returns an allocated object array.
Parameter | Description |
type
| Type of objects in the array. The following types are supported:
T_BOOLEAN | A Boolean object.
| T_BYTE | A Byte object.
| T_CHAR | A Character object.
| T_CLASS | A Class object (use szSig to specify the class).
| T_DOUBLE | A Double object.
| T_FLOAT | A Float object.
| T_INT | An Integer object.
| T_LONG | A Long object.
| T_SHORT | A Short object.
|
|
cItems
| Number of elements in the array to allocate.
|
szSig
| Signature of the class if type is T_CLASS. (For example, "java/awt/Rectangle".)
|
HObject* __cdecl ClassClassToClassObject(ClassClass *cls);
Retrieves a java.lang.Class object for a ClassClass.
Note This method can cause a garbage collection to occur; guard
any objects that you want to use after calling this method.
Return Value:
Returns a java.lang.Class object.
Parameter | Description |
cls
| A ClassClass pointer.
|
ClassClass * __cdecl ClassObjectToClassClass(HObject *object);
Retrieves a ClassClass pointer from a java.lang.Class object.
Note This method can cause a garbage collection to occur; guard any objects that
you want to use after calling this method.
Return Value:
Returns a ClassClass pointer.
Parameter | Description |
object
| A java.lang.Class object.
|
Hjava_lang_Object *__cdecl convert_IUnknown_to_Java_Object(IUnknown *punk, Hjava_lang_Object *phJavaClass, int fAssumeThreadSafe);
Returns a Java callable wrapper that can be used to access the specified interface pointer. The virtual machine will keep a reference to this interface pointer. If fAssumeThreadSafe is false, the virtual machine auto-marshals all COM calls to the current COM context.
Hjava_lang_Object *__cdecl convert_IUnknown_to_Java_Object(IUnknown *punk, ClassClass *pClassClass, int fFreeThreaded);
Returns a Java callable wrapper that can be used to access the specified interface pointer. The virtual machine will keep a reference to this interface pointer. If fAssumeThreadSafe is false, the virtual machine auto-marshals all COM calls to the current COM context.
IUnknown *__cdecl convert_Java_Object_to_IUnknown(Hjava_lang_Object *phJavaObject, const IID *pIID);
Returns an interface pointer usable from the current COM context.
Hjava_lang_Object *__cdecl convert_ptr_to_jcdw(void *pExtData, Hjava_lang_Object *phJavaClass);
Returns a data wrapper object of the supplied class type that points at the supplied data pointer. The memory is not owned by the virtual machine.
long __cdecl do_execute_java_method(ExecEnv *ee, void *obj, char *method_name,
char *signature, struct methodblock *mb, bool_t isStaticCall, ...);
Calls a Java method.
Return Value:
Returns TRUE if successful, or FALSE otherwise.
Parameter | Description |
ee
| Placeholder for execution environment, which is not needed by the Microsoft VM. This parameter should be set to NULL.
|
obj
| Object pointer.
|
method_name
| Name of the method to invoke. Set to NULL if using a method block.
|
signature
| Types of parameters passed to the constructor. See execute_java_dynamic_method
for a description of signature characters. Pass NULL if using a method block.
|
*mb
| Address of the cached method block data structure. Use get_methodblock to retrieve this. The underlying structure of the method block is not defined; it is used only to prevent accidental type misuse using the alternative, PVOID.
|
isStaticCall
| True if calling a static method, or false otherwise. |
Remarks:
This is a helper function for the execute_java_static_method and execute_java_dynamic_method functions. It can be used when making repeated calls to a method to avoid the overhead of name lookup on each call. Note that invoking a Java method can cause garbage collections.
The following example demonstrates calling this function for repeated access to the Rectangle.move method:
struct {
Hjava_awt_Rectangle *phRectangle;
} gc;
struct methodblock *pmb = get_methodblock(gc.phRectangle, "move", "(II)V");
for (i=0; i < 10; i++)
{
do_execute_java_method(NULL, gc.phRectangle, NULL, NULL, pmb, FALSE, x, y);
}
int64_t __cdecl do_execute_java_method64(ExecEnv *ee, void *obj, const char *method_name, const char *signature, struct methodblock *mb, bool_t isStaticCall, ...);
Calls a Java method or constructor and returns a 64 bit int.
Return Value:
Returns TRUE if successful, or FALSE otherwise.
Parameter | Description |
ee
| Placeholder for execution environment, which is not needed by the Microsoft VM. This parameter should be set to NULL.
|
obj
| Object pointer.
|
*method_name
| Name of the method to invoke. Set to NULL if using a method block.
|
signature
| Types of parameters passed to the constructor. See execute_java_dynamic_method
for a description of signature characters. Pass NULL if using a method block.
|
*mb
| Address of the cached method block data structure. Use get_methodblock to retrieve this. The underlying structure of the method block is not defined; it is used only to prevent accidental type misuse using the alternative, PVOID.
|
isStaticCall
| True if calling a static method, or false otherwise. |
Remarks:
This is a helper function for the execute_java_static_method and execute_java_dynamic_method functions. It can be used when making repeated calls to a method to avoid the overhead of name lookup on each call. Note that invoking a Java method can cause garbage collections.
int64_t __cdecl do_execute_java_methodV(ExecEnv *ee, void *obj, const char *method_name, const char *signature, struct methodblock *mb, bool_t isStaticCall, va_list args);
Calls a Java method or constructor and returns a 64 bit int.
Return Value:
Returns TRUE if successful, or FALSE otherwise.
Parameter | Description |
ee
| Placeholder for execution environment, which is not needed by the Microsoft VM. This parameter should be set to NULL.
|
obj
| Object pointer.
|
*method_name
| Name of the method to invoke. Set to NULL if using a method block.
|
signature
| Types of parameters passed to the constructor. See execute_java_dynamic_method
for a description of signature characters. Pass NULL if using a method block.
|
*mb
| Address of the cached method block data structure. Use get_methodblock to retrieve this. The underlying structure of the method block is not defined; it is used only to prevent accidental type misuse using the alternative, PVOID.
|
isStaticCall
| True if calling a static method, or false otherwise.
args
| The va_list used instead of ellipses.
| |
void __cdecl exceptionClear(ExecEnv *ee);
Clears any pending exceptions.
Parameter | Description |
ee
| Placeholder for execution environment, which is not needed by the Microsoft VM.
Set this parameter to NULL.
|
void __cdecl exceptionDescribe(ExecEnv *ee);
Invokes printStackTrace on the pending exception.
Parameter | Description |
ee
| Placeholder for execution environment, which is not needed by the Microsoft VM.
Set this parameter to NULL.
|
bool_t __cdecl exceptionOccurred(ExecEnv *ee);
Determines if an exception has occurred in the called Java method without exiting the native code.
Return Value:
Returns TRUE if an exception occurred, or FALSE otherwise.
Parameter | Description |
ee
| Placeholder for the execution environment, which is not needed by the Microsoft VM.
Set this parameter to NULL.
|
void exceptionSet(ExecEnv *ee, HObject *phThrowable);
Sets the pending exception. Calling exceptionSet(ee, NULL) produces the same result as calling exceptionClear(ee).
Return Value:
No return value.
Parameter | Description |
ee
| Placeholder for the execution environment, which is not needed by the Microsoft VM.
Set this parameter to NULL.
|
phThrowable
| A pointer to the exception to set.
|
HObject* __cdecl execute_java_constructor(ExecEnv *ee, char *classname,
ClassClass *cb, char *signature, ...);
Allocates a new Java object and invokes a constructor.
Parameter | Description |
ee
| Placeholder for execution environment, which is not needed by the Microsoft VM. This parameter should be set to NULL.
|
classname
| Name of the class if the cb parameter is NULL. Use forward slashes (/) instead of dots as
package delimiters. (For example, "java/lang/System".)
|
cb
| Address of the class object. Use NULL and provide classname if not known.
|
signature
| Types of parameters passed to the constructor. See execute_java_dynamic_method for a description of signature characters. The return type for all constructors, 'V', is automatically appended and should not be specified.
|
HObject* __cdecl execute_java_constructorV(ExecEnv *ee, const char *classname,
ClassClass *cb, const char *signature, va_list args);
Allocates a new Java object and invokes a constructor. This method accepts a va_list argument list as a paramenter instead of ellipses.
Parameter | Description |
ee
| Placeholder for execution environment, which is not needed by the Microsoft VM. This parameter should be set to NULL.
|
classname
| Name of the class if the cb parameter is NULL. Use forward slashes (/) instead of dots as
package delimiters. (For example, "java/lang/System".)
|
cb
| Address of the class object. Use NULL and provide classname if not known.
|
signature
| Types of parameters passed to the constructor. See execute_java_dynamic_method for a description of signature characters. The return type for all constructors, 'V', is automatically appended and should not be specified.
|
args
| Additional arguments.
|
long __cdecl execute_java_dynamic_method(ExecEnv *ee, HObject *obj, char
*method_name, char *signature, ...);
Invokes a Java dynamic method.
Parameter | Description |
ee
| Placeholder for the execution environment, which is not needed by the Microsoft VM.
Set this parameter to NULL.
|
obj
| Address to the Java object containing method.
|
method_name
| Name of the method to be called.
|
signature
| Types of parameters and return type of the method (see below) .
|
Remarks:
The signature parameter specifies the parameters and return type of the method by enclosing the character codes for parameter types in parentheses, followed by the character code for the return type. The following table shows the mapping of types to signature characters:
Character | Java Type
|
[ | array
|
Z | boolean
|
B | byte
|
C | char
|
D | double
|
F | float
|
I | int
|
J | long
|
L | object
|
S | short
|
V | void
|
Arrays must be followed by the array type. For example, "[C" for a character array. For multidimensional arrays, repeat "[" for the number of dimensions. For example, "[[Z" signifies a two-dimensional boolean array.
For objects, the signature is followed by the object class name and ends with a semicolon (;). For example, the signature for the a Rectangle object is "Ljava/awt/Rectangle;"
The following example uses this function to call the Rectangle.move method with two integer parameters to the method, x and y:
long lrval = execute_java_dynamic_method(NULL, phRectangle, "move","(II)V", x, y);
int64_t __cdecl execute_java_dynamic_method64(ExecEnv *ee, HObject *obj, char
*method_name, char *signature, ...);
Invokes a Java dynamic method. This method is equivalent to the execute_java_dynamic_method except it returns a 64 bit value instead of a 32 bit long.
Return Value:
A 64 bit value.
Parameter | Description |
ee
| Placeholder for the execution environment, which is not needed by the Microsoft VM.
Set this parameter to NULL.
|
obj
| Address to the Java object containing method.
|
method_name
| Name of the method to be called.
|
signature
| Types of parameters and return type of the method.
|
int64_t __cdecl execute_java_dynamic_methodV(ExecEnv *ee, HObject *obj, const char
*method_name, const char *signature, va_list args);
Invokes a Java dynamic method. This method is equivalent to the execute_java_dynamic_method except it returns a 64 bit value instead of a 32 bit long, and accepts a va_list argument list as a parameter.
Return Value:
A 64 bit value.
Parameter | Description |
ee
| Placeholder for the execution environment, which is not needed by the Microsoft VM.
Set this parameter to NULL.
|
obj
| Address to the Java object containing method.
|
method_name
| Name of the method to be called.
|
signature
| Types of parameters and return type of the method.
|
args
| Additional arguments.
|
long __cdecl execute java_interface_method(ExecEnv *ee, HObject *pobj, ClassClass j_interface,
const char *method_name, const char *signature, ...);
Invokes a Java interface method.
Parameter | Description |
ee
| Placeholder for the execution environment, which is not needed by the Microsoft VM.
Set this parameter to NULL.
|
pobj
| Address to the Java object containing method.
|
j_interface
| A java class interface.
|
method_name
| Name of the method to be called.
|
signature
| Types of parameters and return type of the method.
|
int64_t __cdecl execute java_interface_method64(ExecEnv *ee, HObject *pobj, ClassClass j_interface,
const char *method_name, const char *signature, ...);
Invokes a Java interface method. This method is equivalent to the execute_java_interface_method, except it returns a 64 bit value instead of a 32 bit long.
Return Value:
A 64 bit value.
Parameter | Description |
ee
| Placeholder for the execution environment, which is not needed by the Microsoft VM.
Set this parameter to NULL.
|
pobj
| Address to the Java object containing method.
|
j_interface
| A java class interface.
|
method_name
| Name of the method to be called.
|
signature
| Types of parameters and return type of the method.
|
int64_t __cdecl execute_java_interface_methodV(ExecEnv *ee, HObject *pobj,
ClassClass j_interface, const char *method_name, const char *signature, va_list args);
Invokes a Java interface method. This method is equivalent to the execute_java_interface_method, except it returns a 64 bit value instead of a 32 bit long and accepts a va_list argument list as a a parameter.
Return Value:
A 64 bit value.
Parameter | Description |
ee
| Placeholder for the execution environment, which is not needed by the Microsoft VM.
Set this parameter to NULL.
|
pobj
| Address to the Java object containing method.
|
j_interface
| A java class interface.
|
method_name
| Name of the method to be called.
|
signature
| Types of parameters and return type of the method.
|
args
| Additional arguments.
|
long __cdecl execute_java_static_method(ExecEnv *ee, ClassClass *cb,
char *method_name, char *signature, ...);
Invokes a Java static method.
Parameter | Description |
ee
| Placeholder for execution environment, which is not needed by the Microsoft VM.
Pass NULL.
|
cb
| Address of the class object, obtained with the FindClass function.
|
method_name
| Name of the method to be called.
|
signature
| Types of parameters passed to the constructor. For a description of signature characters, see execute_java_dynamic_method.
|
int64_t __cdecl execute_java_static_method64(ExecEnv *ee, ClassClass *cb,
char *method_name, char *signature, ...);
Invokes a Java static method. This method is equivalent to the execute_java_dynamic_method, except it returns a 64 bit value instead of a 32 bit long.
Return Value:
A 64 bit value.
Parameter | Description |
ee
| Placeholder for the execution environment, which is not needed by the Microsoft VM.
Pass NULL.
|
cb
| Address of the class object, obtained with the FindClass function.
|
method_name
| Name of the method to be called.
|
signature
| Types of parameters passed to the constructor. For a description of signature characters, see execute_java_dynamic_method64.
|
int64_t __cdecl execute_java_static_methodV(ExecEnv *ee, ClassClass *cb,
const char *method_name, const char *signature, va_list args);
Invokes a Java static method. This method is equivalent to the execute_java_dynamic_method, except it returns a 64 bit value instead of a 32 bit long, and accepts a va_list argument list as a parameter.
Return Value:
A 64 bit value.
Parameter | Description |
ee
| Placeholder for the execution environment, which is not needed by the Microsoft VM.
Pass NULL.
|
cb
| Address of the class object, obtained with the FindClass function.
|
method_name
| Name of the method to be called.
|
signature
| Types of parameters passed to the constructor. For a description of signature characters, see execute_java_dynamic_method64.
|
args
| Additional arguments.
|
__int32 __cdecl Field_GetValue(HObject *obj, struct fieldblock * field);
__int64 __cdecl Field_GetValue64(HObject *obj, struct fieldblock * field);
float __cdecl Field_GetFloat(HObject *obj, struct fieldblock * field);
double __cdecl Field_GetDouble(HObject *obj, struct fieldblock * field);
#define Field_GetBoolean(obj,field) ((bool_t) Field_GetValue(obj,field))
#define Field_GetByte(obj,field) ((signed char) Field_GetValue(obj,field))
#define Field_GetChar(obj,field) ((unicode) Field_GetValue(obj,field))
#define Field_GetShort(obj,field) ((short) Field_GetValue(obj,field))
#define Field_GetInt(obj,field) Field_GetValue(obj,field)
#define Field_GetLong(obj,field) Field_GetValue64(obj,field)
#define Field_GetObject(obj,field) ((HObject*) Field_GetValue(obj,field))
#define Field_GetFloat(obj,field) Field_GetFloat(obj,field)
#define Field_GetDouble(obj,field) Field_GetDouble(obj,field)
Retrieves the value of the specified field.
Return Value:
Returns a value of a type determined by the function.
Parameter | Description |
obj
| Address of the object that the field belongs to.
|
field
| Field block of the field.
|
Remarks:
These functions operate on static or non-static fields, including both of the component object model (COM) MapsTo fields and the fields in Java objects.
unsigned __cdecl Field_GetOffset(struct fieldblock * field);
Returns the offset of dynamic fields in the class.
Return Value:
Returns the offset of the field relative to the object for non-static fields. Returns 0 for static fields.
Parameter | Description |
field
| Field block of the field. The underlying structure of field block is not defined;
it is used only to prevent accidental type misuse using the alternative, PVOID.
|
Remarks:
Note that this function accounts for the 'MSReserved' value at the top of
structures generated by msjavah. This means you can just add this value to the base
of the object to get to the data.
PVOID __cdecl Field_GetStaticPtr(struct fieldblock * field);
Returns an address of the static data.
Return Value:
Returns an address to the data for static fields, or NULL for non-static fields.
Parameter | Description |
field
| Field block of the field. The underlying structure of field block is not defined;
it is used only to prevent accidental type misuse using the alternative, PVOID.
|
void __cdecl Field_SetValue(HObject *obj, struct fieldblock * field, __int32 value);
void __cdecl Field_SetValue64(HObject *obj, struct fieldblock * field, __int64 value);
void __cdecl Field_SetFloat(HObject *obj, struct fieldblock * field, float value);
void __cdecl Field_SetDouble(HObject *obj, struct fieldblock * field, double value);
#define Field_SetBoolean(obj,field,value) Field_SetValue(obj,field,(bool_t)(value))
#define Field_SetByte(obj,field,value) Field_SetValue(obj,field,(signed char)(value))
#define Field_SetChar(obj,field,value) Field_SetValue(obj,field,(unicode)(value))
#define Field_SetShort(obj,field,value) Field_SetValue(obj,field,(short)(value))
#define Field_SetInt(obj,field,value) Field_SetValue(obj,field,value)
#define Field_SetLong(obj,field,value) Field_SetValue64(obj,field,value)
#define Field_SetObject(obj,field,value) Field_SetValue(obj,field,(__int32)(value))
#define Field_SetFloat(obj,field,value) Field_SetFloat(obj,field,value)
#define Field_SetDouble(obj,field,value) Field_SetDouble(obj,field,value)
Sets the value of the specified field.
Parameter | Description |
obj
| Address of the object that the field belongs to.
|
field
| Field block of the field.
|
Remarks:
These functions operate on static or non-static fields, including both of the COM MapsTo fields and the fields in Java objects.
ClassClass* __cdecl FindClass(ExecEnv *ee, char *classname, bool_t resolve);
Retrieves a class object pointer for a named class.
Return Value:
Returns a pointer to the class.
Parameter | Description |
ee
| Placeholder for execution environment, which is not needed by the Microsoft VM.
Set this parameter to NULL.
|
classname
| Name of the class to locate.
|
resolve
| Ignored. Classes found will always be ignored.
|
Remarks:
Use this function to get a pointer to a class, named by classname. This pointer can be
used in the execute_java_static_method function to identify the class.
ClassClass* __cdecl FindClassEx(char *pszClassName,DWORD dwFlags);
Retrieves a class object pointer for a named class, according to the specified flags.
Return Value:
Returns a pointer to the class.
Parameter | Description |
pszClassName
| Name of the class to locate.
|
dwFlags
| One of the following flags:
FINDCLASSEX_NOINIT
| If the class is a system class, will prevent the classes static initializer from running.
| FINDCLASSEX_IGNORECASE
| Will perform a case-insensitive validation of the class name, as opposed to the case-sensitive validation that normally occurs.
| FINDCLASSEX_SYSTEMONLY
| Will only look for the named class as a system class.
|
|
Remarks:
This method is similar to the FindClass method, but accepts arguments to control the class load operation.
int __cdecl GCDisable();
Increments the block count and disables garbage collection.
Return Value:
Returns TRUE if successful, or FALSE otherwise.
Remarks:
Use this function to disable garbage collection after you have enabled it using
GCEnable.
int __cdecl GCDisableCount();
Disables the counting used by GCEnable and GCDisable.
Return Value:
Returns the current count.
Remarks:
Used for diagnostic purposes. Since the use of GCEnable and GCDisable requires a counter, this provides a way to verify that the count is what is expected.
void __cdecl GCDisableMultiple(int cDisable);
Increments the block count a specified number of times.
Parameter | Description |
cDisable
| Number of times to increment the block count.
|
Remarks:
This function is useful when you have previously called GCEnableCompletely to allow garbage collection on all referenced objects, but later want to reinstate the block count with one call. The following example shows enabling garbage collection around a sleep call.
int nEnable = GCEnableCompletely();
Sleep( (int) millis );
GCDisableMultiple(nEnable);
int __cdecl GCEnable();
Decrements the block count and enables garbage collection by the VM.
Return Value:
Returns TRUE if successful, or FALSE otherwise.
Remarks:
When calling a native function from within Java, garbage collection is blocked by default.
If the native function call is going to take some time, you can enable garbage collection with this call.
However, you should first use the GCFramePush function to allow the garbage collector to
track any Java objects that you care about during garbage collection.
int __cdecl GCEnableCompletely();
Decrements the block count to 0 and enables garbage collection by the VM.
Return Value:
Returns the block count before entering this function.
Remarks:
This function enables garbage collection, regardless of the number of calls previously made to GCDisable, incrementing the block count.
void __cdecl GCFramePop(PVOID pGCFrame);
Restores the GCFrame with current values for members of the structure.
Parameter | Description |
pGCFrame
| Address of a garbage collection frame that references a structure with Java objects that are being tracked.
|
void __cdecl GCFramePush(PVOID pGCFrame, PVOID pObjects,
DWORD cbObjectStructSize);
Informs the VM garbage collector of a GCFrame to track.
Parameter | Description |
pGCFrame
| Address of a garbage collection frame referencing the pObjects structure.
|
pObjects
| Structure containing the Java objects to track during garbage collection.
|
cbObjectStructSize
| Size of pObjects structure.
|
Remarks:
The garbage collector initializes the structure referenced by pObjects to
NULL.
void __cdecl GCFreeHandle(HObject **pphobj);
Frees a strong pointer, originally obtained using GCNewHandle.
Parameter | Description |
pphobj
| Pointer to a pointer to be freed.
|
void __cdecl GCFreePtr(HObject **pphobj);
Frees a garbage collection pointer originally obtained using GCGetPtr.
Parameter | Description |
pphobj
| Pointer to a pointer to be freed.
|
HObject** __cdecl GCGetPtr(HObject *phobj);
Allocates a "weak" pointer for an object, and then updates it when garbage collection occurs.
Return Value:
Returns an address to a pointer to a Java object handle.
Parameter | Description |
phobj
| Address of a Java object.
|
Remarks:
Given a pointer to an object, this function allocates and returns the address of that object pointer, and then updates the contained pointer when GC occurs. Note that if the object gets freed during GC, the value of the contained pointer will be NULL. A "weak" pointer is different from a "strong" pointer (as allocated by GCNewHandle). A weak pointer will not block garbage collection (removal) of the referenced object, but a strong pointer will. (Strong pointers are scanned like any other object during GC; weak pointers are updated after the GC has been completed.)
HObject** __cdecl GCNewHandle(HObject *phobj);
Creates a "strong pointer" to an object.
Return Value:
Returns an address to the object pointer.
Parameter | Description |
phobj
| Object that is be referenced.
|
Remarks:
Using this function is similar to placing an object in a GCFrame; however, strong pointers can be stored statically across calls. A strong pointer prevents the object from being collected as garbage, whereas a weak pointer only tracks the object's movement.
void __cdecl GCSetObjectReferenceForHandle (HObject** handle, HObject* phobj);
GC-safe method for updating the contents of a handle.
Return Value:
No return value.
Parameter | Description |
handle
| The result of calling GCGetPtr for a weak pointer or GCNewHandle for a strong handle.
|
phobj
| The new object pointer.
|
Remarks:
If handles are not updated using a GC-safe method, the VM will fault during the next GC.
void __cdecl GCSetObjectReferenceForObject (HObject** location, HObject* phobj);
GC-safe method for updating the fields in an object.
Return Value:
No return value.
Parameter | Description |
location
| Pointer to a field of an object.
|
phobj
| The new object pointer.
|
Remarks:
The safest method to set a field in an object is to use the Field_SetValue method. If objects are not updated using a GC-safe method, the VM will fault during the next GC.
struct methodblock* __cdecl get_methodblock(HObject *pjobj, char *method_name,
char *signature);
Retrieves a pointer to a method block structure containing the class name, method name, and parameter and return types of a method.
Return Value:
Returns a handle to a method in the given object specified by name and signature. This is useful for functions like do_execute_java_method,
which can use this information directly instead of having to look it up.
Parameter | Description |
pjobj
| Address of the structure.
|
method_name
| Name of the method to invoke.
|
signature
| Types of parameters passed to the constructor. For a description of signature characters, see execute_java_dynamic_method.
|
__int64 __cdecl GetCurrentJavaTimeMillis();
Returns the same result as defined by java.lang.System.currentTimeMillis().
ClassClass * __cdecl GetNativeMethodCallersClass();
Determines the class type of the caller.
Return Value:
Returns a pointer to the class type of the caller.
struct methodblock* __cdecl GetNativeMethodCallersMethodInfo();
Retrieves information about the caller's method.
Return Value:
Returns a method block pointer.
HObject *getPendingException(ExecEnv *ee);
Retrieves a pending exception.
Return Value:
Returns the pending exception; if no exception is pending, NULL is returned.
Parameter | Description |
ee
| Placeholder for the execution environment, which is not needed by the Microsoft VM. Pass NULL.
|
HResult __cdecl HResultFromException(OBJECT* exception_object);
Creates an HRESULT return type from a Java exception object. This function prototype is found in the nativcom.h header file.
Return Value:
An HRESULT type.
Parameter | Description |
exception_object
| The exception object to covert to an HRESULT.
|
BOOL is_instance_of(JHandle *phobj, ClassClass *dcb, ExecEnv *ee);
Determines whether the specified object phobj can be cast to the specified class type dcb.
Return Value:
Returns TRUE if the object can be cast to the class type; otherwise, returns false.
Parameter | Description |
phobj
| A pointer to an object.
|
dcb
| A class type.
|
ee
| Placeholder for the execution environment, which is not needed by the Microsoft VM. Pass NULL.
|
BOOL is_subclass_of(ClassClass *cb, ClassClass *dcb, ExecEnv *ee);
Determines whether the class type cb is a subclass of type dcb.
Return Value:
Returns TRUE if the class is a subclass of dcb; otherwise, returns false.
Parameter | Description |
cb
| The class type that is being tested.
|
dcb
| The class type to test against.
|
ee
| Placeholder for the execution environment, which is not needed by the Microsoft VM. Pass NULL.
|
BOOL ImplementsInterface(ClassClass *cb, ClassClass *icb, ExecEnv *ee);
Determines whether the class type cb implements the interface represented by the icb class type.
Return Value:
Returns TRUE if the class implements the specified interface.
Parameter | Description |
cb
| The class type to test.
|
icb
| The class type that represents an interface to test against.
|
ee
| Placeholder for the execution environment, which is not needed by the Microsoft VM. Pass NULL.
|
BOOL __cdecl isInstanceOf(JHandle *phobj, char *classname);
Determines if a specified Java object is an instance of a particular class.
Return Value:
Returns TRUE if the handle is an instance of the class, or FALSE otherwise.
Parameter | Description |
pohobj
| Address of the Java handle.
|
classname
| Name of the Java class.
|
struct methodblock* __cdecl j2chook_getmethodblock(J2CMethodHookInfo *phookinfo);
Returns the methodblock of the target method.
WORD __cdecl j2chook_getsizeofuserdata(J2CMethodHookInfo *phookinfo);
Gets size of user data in the MCCustomMethod descriptor.
LPVOID __cdecl j2chook_getuserdata(J2CMethodHookInfo *phookinfo);
Gets writable pointer to user data in the MCCustomMethod descriptor.
WORD __cdecl j2chook_getvtblindex(J2CMethodHookInfo *phookinfo);
Returns the vtable index of the target method.
char* __cdecl javaString2CString(Hjava_lang_String *s, char *buf, int buflen);
Retrieves the characters of the Java String object into a C string buffer.
Return Value:
Returns the address of the C string.
Parameter | Description |
s
| Java String object.
|
buf
| C string buffer.
|
buflen
| Length of the C string buffer.
|
Remarks:
Use this function in place of the JDK makeCString function which is unsupported by the Microsoft Raw Native Interface. No allocation occurs with his function.
int __cdecl javaStringLength(Hjava_lang_String *s);
Retrieves the length of the Java String object.
Return Value:
Returns the number of characters in the string.
Parameter | Description |
s
| Java String object.
|
unicode * __cdecl javaStringStart (HString *string);
Returns a temporary pointer to the first character of the Java String object. It is important that you use this method rather than try to manipulate RNI structures that handle string types. The Microsoft virtual machine handles strings differently in certain situations, and strings may be stored with multiple objects.
Return Value:
Returns a string pointer.
Parameter | Description |
string
| The String handle to reference.
|
Remarks:
Note that this pointer may change following garbage collection.
int __cdecl jcdw_java_owned(Hjava_lang_Object *phJCDW);
Returns true if the virtual machine frees the non-garbage-collected heap memory that this data wrapper contains when the data wrapper is garbage collected.
Parameter | Description |
*phJCDW
| The data pointer to the heap memory.
|
int __cdecl jcdw_memory_freed_on_gc(Hjava_lang_Object *phJCDW);
Returns true if the virtual machine allocated the non-garbage-collected heap memory contained by the data wrapper.
Parameter | Description |
*phJCDW
| The data pointer to the heap memory.
|
unsigned int __cdecl jcdwClassOffsetOf(Hjava_lang_Object *phJCDWClass, const char *pFieldName);
Returns the byte offset within the non-garbage-collected heap memory to the specified field name from the supplied java.lang.Class object.
Parameter | Description |
*phJCDW
| The data pointer to the heap memory.
|
*pFieldName
| The specified field.
|
unsigned int __cdecl jcdwClassSizeOf(Hjava_lang_Object *phJavaClass);
Returns the size of the non-garbage-collected heap memory used by instances of the
supplied java.lang.Class object.
Parameter | Description |
*phJavaClass
| The data pointer to the heap memory.
|
void* __cdecl jcdwGetData(Hjava_lang_Object *phJCDW);
Returns the data pointer to the non-garbage-collected heap memory contained by the data wrapper object.
Parameter | Description |
*phJCDW
| The data pointer to be replaced.
|
void* __cdecl jcdwNewData(Hjava_lang_Object *phJCDW, unsigned int numBytes);
Replaces the data pointer contained in the data wrapper with a new quantity of non-garbage-collected heap memory. The previous memory, if any, is freed if it is owned by the VM.
Parameter | Description |
*phJCDW
| The data pointer to be replaced.
|
numBytes
| The size of the heap memory in bytes.
|
unsigned int __cdecl jcdwOffsetOf(Hjava_lang_Object *phJCDW, const char *pFieldName);
Returns the byte offset within the non-garbage-collected heap memory to the specified field name.
Parameter | Description |
*phJCDW
| The data pointer to the heap memory.
|
*pFieldName
| The specified field.
|
int __cdecl jcdwSetData(Hjava_lang_Object *phJCDW, LPVOID pv);
Replaces the data pointer that this data wrapper represents with the specified pointer.
Parameter | Description |
*phJCDW
| The data pointer to be replaced.
|
pv
| The specified data pointer. |
unsigned int __cdecl jcdwSizeOf(Hjava_lang_Object *phJCDW);
Returns the size of the non-garbage-collected heap memory contained by the data wrapper object.
Parameter | Description |
*phJCDW
| The data pointer to the heap memory.
|
int __cdecl jio_snprintf(char *str, size_t count, const char *fmt, ...);
Prints to a string with a buffer limit.
Return Value:
Returns the length of the string after printing to it.
Parameter | Description |
str
| String to print to.
|
count
| Limit of the number of characters to print.
|
fmt
| Format string (see sprintf).
|
int __cdecl jio_vsnprintf(char *str, size_t count, const char *fmt, va_list args);
Prints to a string with a buffer limit using a va_list macro for arguments.
Return Value:
Returns the length of the string after printing to it.
Parameter | Description |
str
| String to print to.
|
count
| Limit of the number of characters to print.
|
fmt
| Format string (see sprintf).
|
args
| Argument list.
|
Hjava_lang_String* __cdecl makeJavaString(char *str, int len);
Constructs a Java string from a given ANSI C character buffer, converting it to UNICODE.
Return Value:
Returns a string formatted as a Java String object.
Parameter | Description |
str
| C string to convert.
|
len
| Number of characters in the C string, excluding the terminating NULL.
|
Hjava_lang_String* __cdecl makeJavaStringW( unicode *pszwSrc, int cch );
Constructs a Java string from a Unicode C character buffer.
Return Value:
Returns a string formatted as a Java String object.
Parameter | Description |
pszwSrc
| C string to convert.
|
cch
| Number of characters in the C string, excluding the terminating NULL.
|
Hjava_lang_String* __cdecl makeJavaStringFromUtf8(const char *pszUtf8);
Creates a new Java String object, initialized from a NULL-terminated, UTF8-formatted, C string.
Return Value:
Returns a string formatted as a Java String object.
Parameter | Description |
pszUtf8
| Initialization string.
|
Remarks:
Unlike the other RNI string conversion functions, makeJavaStringFromUtf8 does not require a character count but does requires NULL termination of the UTF8 string.
HArrayOfByte* __cdecl MakeByteString(char *str, long len);
Creates a new array of bytes initialized from the C string.
Return Value:
Returns the converted byte string.
Parameter | Description |
str
| C string to convert.
|
len
| Number characters in the string, excluding the terminating NULL character.
|
HRESULT __cdecl MarshalCallToJavaObjectHostThread(Hjava_lang_Object *phobj, int64_t *pResult);
Reexecutes the RNI method on the apartment thread ID for the supplied Java object. This and MarshalCallToJavaThreadID return the following sets of HRESULTs:
S_OK -- The call was successfully marshaled to the target thread. The marshaled call may have generated an exception, which can be checked by calling exceptionOccurred.
S_FALSE -- The call did not require marshaling to the other thread. The currently executing thread is the target thread.
E_<> -- An error occurred inside the MarshalCall API, such as invalid arguments, out of memory, and so on.
The typical use of these APIs is to call the appropriate MarshalCall API and if the HRESULT is S_FALSE, then execute the rest of the RNI method, otherwise return with the value contained in pResult.
HRESULT __cdecl MarshalCallToJavaThreadId(JAVATID tid, int64_t *pResult);
Reexecutes the RNI method on the supplied thread ID for the supplied Java object. This and MarshalCallToJavaObjectHostThread return the following sets of HRESULTs:
S_OK -- The call was successfully marshaled to the target thread. The marshaled call may have generated an exception, which can be checked by calling exceptionOccurred.
S_FALSE -- The call did not require marshaling to the other thread. The currently executing thread is the target thread.
E_<> -- An error occurred inside the MarshalCall API, such as invalid arguments, out of memory, and so on.
The typical use of these APIs is to call the appropriate MarshalCall API and if the HRESULT is S_FALSE, then execute the rest of the RNI method, otherwise return with the value contained in pResult.
int __cdecl Member_GetAttributes(PVOID member);
Retrieves a combination of the ACC_XXX flags for a field or method,
as appears in the Java class file.
Return Value:
Returns attributes flags.
Parameter | Description |
member
| Method or field block of the member.
|
ClassClass * __cdecl Member_GetClass(PVOID member);
Retrieves the name of the class that the field or method is implemented in.
Return Value:
Returns the name of a class.
Parameter | Description |
member
| Address of a method or field block.
|
const char * __cdecl Member_GetName(PVOID member);
Retrieves the method or field name.
Return Value:
Returns the method or field name.
Parameter | Description |
member
| Address of a method or field block.
|
const char * __cdecl Member_GetSignature(PVOID member);
Retrieves the signature of the field or method.
Return Value:
Returns a signature.
Parameter | Description |
member
| Address of a method or field block.
|
void __cdecl monitorEnter(unsigned int object);
Enters a synchronization object.
Return Value:
No return value.
Parameter | Description |
object
| Synchronization object (cast as an int) to enter.
|
Remarks:
You can use the ObjectMonitorEnter macro to automatically cast the synchronization object to an int and call this method.
void __cdecl monitorExit(unsigned int object);
Exits a synchronization object.
Return Value:
No return value.
Parameter | Description |
object
| Synchronization object (cast as an int) to exit.
|
Remarks:
You can use the ObjectMonitorExit macro to automatically cast the synchronization object to an int and call this method.
void __cdecl monitorNotify(unsigned int object);
Wakes up a single thread that is waiting on this object's monitor.
Return Value:
No return value.
Parameter | Description |
object
| Synchronization object (cast as an int).
|
Remarks:
You can use the ObjectMonitorNotify macro to automatically cast the synchronization object to an int and call this method. This method is the native equivalent of the Java.lang.Object.notify method.
void __cdecl monitorNotifyAll(unsigned int object);
Wakes up all threads that are waiting on this object's monitor.
Return Value:
No return value.
Parameter | Description |
object
| Synchronization object (cast as an int).
|
Remarks:
You can use the ObjectMonitorNotifyAll macro to automatically cast the synchronization object to an int and call this method. This method is the native equivalent of the Java.lang.Object.notifyAll method.
void __cdecl monitorWait(unsigned int object);
Waits to be notified by another thread of a change in this object.
Return Value:
No return value.
Parameter | Description |
object
| Synchronization object (cast as an int).
|
Remarks:
You can use the ObjectMonitorWait macro to automatically cast the synchronization object to an int and call this method. This method is the native equivalent of the Java.lang.Object.wait method.
ClassClass * __cdecl Object_GetClass(HObject *obj);
Retrieves class that the object points to.
Return Value:
Returns a class object pointer.
Parameter | Description |
obj
| Class object to retrieve.
|
BOOL __cdecl PrepareThreadForJava(PVOID pThreadEntryFrame);
Thread entry function for calls into the VM.
Return Value:
Returns true if successful; otherwise, returns false.
Parameter | Description |
pThreadEntryFrame
| An instance of a thread entry frame. This pointer is maintained by the VM and the same pointer should be used in UnprepareThreadForJava when exiting the VM.
|
Remarks:
This method prepares a Java thread for entering the VM so that calls can be safely made from the thread to native methods. Garbage collection is disabled in between PrepareThreadForJava and UnprepareThreadForJava. An application can hang if each thread waits until it's about to exit before calling UnprepareThreadForJava.
The following code sample demonstrates the use of invocation APIs:
Demonstrates the use of the PrepareThreadForJava and UnprepareThreadForJava
invocation APIs.
//
#include <windows.h>
#include <stdio.h>
#include <native.h>
void main(int argc, char *argv[])
{
ThreadEntryFrame threadEntryFrame;
ClassClass *pClass;
Call this API before calling into the Microsoft VM to allow it
to allocate any per-thread structures and to do any first-time
initialization. After return from this call, Java objects may be
accessed or RNI APIs may be called.
if (PrepareThreadForJava(&threadEntryFrame)) {
pClass = FindClass(NULL, "TestClass", TRUE);
if (pClass != NULL) {
execute_java_static_method(NULL, pClass, "someMethod", "()V");
} else {
printf("Failed to find class!\n");
}
Detaches the "entry frame" from this thread. After return from this
call, it is no longer safe to directly touch Java objects or call
RNI APIs.
UnprepareThreadForJava(&threadEntryFrame);
} else {
printf("Failed to initialize thread!\n");
}
}
DWORD __declspec(dllexport) __cdecl RNIGetCompatibleVersion();
Allows the VM to determine if the dynamic link library (DLL) is compatible.
Return Value:
Returns the version used by the DLL (defined as RNIVER in native.h).
Remarks:
All raw native interface DLLs must export this function to enable compatibility-checking by the VM.
void __cdecl SignalError(struct execenv *ee, char *ename, char *DetailMessage);
Creates a Java exception object, which is thrown upon returning from the native code.
Parameter | Description |
ee
| Placeholder for executive environment, which is not needed.
This parameter should be NULL.
|
ename
| Name of a valid Throwable exception class or subclass.
|
DetailMessage
| Message to display with the exception. Can be set to NULL.
|
void __cdecl SignalErrorHResult(HRESULT theHRESULT);
Creates a Java exception object from an HRESULT return type. This function prototype is found in the nativcom.h header file.
Return Value:
No return value.
Parameter | Description |
theHRESULT
| The standard return value that indicates whether a function call is a success.
|
void __cdecl SignalErrorPrintf( char *ename, char *pszFormat, ...);
Creates a Java exception object and specifies a format string for exception description to be printed when thrown.
Parameter | Description |
ename
| Name of a valid Throwable exception class or subclass.
|
pszFormat
| Format string. See C printf function.
|
BOOL __cdecl Thread_IsInterrupted(BOOL fResetInterruptFlag);
Checks to see if the current thread is interrupted and optionally resets the interrupt flag. Used in RNI code to see if some other thread has called Thread.interrupt and wants you to stop whatever you are doing.
Parameter | Description |
fResetInterruptFlag
| Indicates whether to reset the interrupt flag.
|
VOID __cdecl UnprepareThreadForJava(PVOID pThreadEntryFrame);
Thread exit function for calls into the VM.
Return Value:
Returns true if successful; otherwise, returns false.
Parameter | Description |
pThreadEntryFrame
| An instance of a thread entry frame. This pointer is maintained by the VM and is the same pointer used in PrepareThreadForJava when entering the VM.
|
Remarks:
This method should be called from any thread when exiting the VM. Garbage collection is disabled in between PrepareThreadForJava and UnprepareThreadForJava. An application can hang if each thread waits until it's about to exit before calling UnprepareThreadForJava.