2003-01-07 14:40:11 +03:00
/ *
2009-05-25 08:01:35 +04:00
Copyright ( C ) 2002 - 2009 Jeroen Frijters
2003-01-07 14:40:11 +03:00
This software is provided ' as - is ' , without any express or implied
warranty . In no event will the authors be held liable for any damages
arising from the use of this software .
Permission is granted to anyone to use this software for any purpose ,
including commercial applications , and to alter it and redistribute it
freely , subject to the following restrictions :
1. The origin of this software must not be misrepresented ; you must not
claim that you wrote the original software . If you use this software
in a product , an acknowledgment in the product documentation would be
appreciated but is not required .
2. Altered source versions must be plainly marked as such , and must not be
misrepresented as being the original software .
3. This notice may not be removed or altered from any source distribution .
Jeroen Frijters
jeroen @frijters . net
* /
using System ;
2008-08-15 16:01:06 +04:00
using System.Collections.Generic ;
2004-08-17 13:05:21 +04:00
using System.Diagnostics ;
2003-01-17 17:34:33 +03:00
using System.Text ;
2003-01-07 14:40:11 +03:00
using System.Reflection ;
2003-01-17 17:34:33 +03:00
using System.Runtime.InteropServices ;
2004-09-09 15:17:55 +04:00
using IKVM.Internal ;
2003-01-07 14:40:11 +03:00
2004-09-05 13:37:58 +04:00
// Java type JNI aliases
using jboolean = System . SByte ;
using jbyte = System . SByte ;
using jchar = System . UInt16 ;
using jshort = System . Int16 ;
using jint = System . Int32 ;
using jsize = System . Int32 ;
using jlong = System . Int64 ;
using jfloat = System . Single ;
using jdouble = System . Double ;
using jobject = System . IntPtr ;
using jstring = System . IntPtr ;
using jclass = System . IntPtr ;
using jarray = System . IntPtr ;
using jobjectArray = System . IntPtr ;
using jbooleanArray = System . IntPtr ;
using jbyteArray = System . IntPtr ;
using jcharArray = System . IntPtr ;
using jshortArray = System . IntPtr ;
using jintArray = System . IntPtr ;
using jlongArray = System . IntPtr ;
using jfloatArray = System . IntPtr ;
using jdoubleArray = System . IntPtr ;
using jthrowable = System . IntPtr ;
using jweak = System . IntPtr ;
using jmethodID = System . IntPtr ;
using jfieldID = System . IntPtr ;
2004-09-09 15:17:55 +04:00
namespace IKVM.Runtime
2003-01-07 14:40:11 +03:00
{
2004-09-09 15:17:55 +04:00
[StructLayout(LayoutKind.Sequential)]
unsafe struct JavaVMOption
{
2007-04-02 12:25:30 +04:00
internal byte * optionString ;
2004-09-09 15:17:55 +04:00
internal void * extraInfo ;
}
[StructLayout(LayoutKind.Sequential)]
unsafe struct JavaVMInitArgs
{
internal jint version ;
internal jint nOptions ;
internal JavaVMOption * options ;
internal jboolean ignoreUnrecognized ;
}
public unsafe sealed class JNI
2003-01-07 14:40:11 +03:00
{
2005-02-23 15:56:15 +03:00
internal static volatile bool jvmCreated ;
internal static volatile bool jvmDestroyed ;
internal const string METHOD_PTR_FIELD_PREFIX = "__<jniptr>" ;
2004-09-09 15:17:55 +04:00
2005-02-02 18:11:26 +03:00
internal static bool IsSupportedJniVersion ( jint version )
{
2007-09-07 09:19:11 +04:00
return version = = JNIEnv . JNI_VERSION_1_1 | | version = = JNIEnv . JNI_VERSION_1_2 | | version = = JNIEnv . JNI_VERSION_1_4 | | version = = JNIEnv . JNI_VERSION_1_6 ;
2005-02-02 18:11:26 +03:00
}
2004-09-09 15:17:55 +04:00
public static int CreateJavaVM ( void * ppvm , void * ppenv , void * args )
2003-01-07 14:40:11 +03:00
{
2004-09-09 15:17:55 +04:00
JavaVMInitArgs * pInitArgs = ( JavaVMInitArgs * ) args ;
// we don't support the JDK 1.1 JavaVMInitArgs
2005-02-02 18:11:26 +03:00
if ( ! IsSupportedJniVersion ( pInitArgs - > version ) | | pInitArgs - > version = = JNIEnv . JNI_VERSION_1_1 )
2004-09-09 15:17:55 +04:00
{
return JNIEnv . JNI_EVERSION ;
}
if ( jvmCreated )
{
return JNIEnv . JNI_ERR ;
}
2008-08-15 16:01:06 +04:00
System . Collections . Hashtable props = new System . Collections . Hashtable ( ) ;
2004-09-09 15:17:55 +04:00
for ( int i = 0 ; i < pInitArgs - > nOptions ; i + + )
2003-01-17 17:34:33 +03:00
{
2007-04-02 12:25:30 +04:00
string option = JNIEnv . StringFromOEM ( pInitArgs - > options [ i ] . optionString ) ;
2004-09-09 15:17:55 +04:00
if ( option . StartsWith ( "-D" ) )
{
int idx = option . IndexOf ( '=' , 2 ) ;
props [ option . Substring ( 2 , idx - 2 ) ] = option . Substring ( idx + 1 ) ;
}
else if ( option . StartsWith ( "-verbose" ) )
{
// ignore
}
else if ( option = = "vfprintf" | | option = = "exit" | | option = = "abort" )
{
// not supported
}
else if ( pInitArgs - > ignoreUnrecognized = = JNIEnv . JNI_FALSE )
2004-08-17 13:05:21 +04:00
{
2004-09-09 15:17:55 +04:00
return JNIEnv . JNI_ERR ;
2004-08-17 13:05:21 +04:00
}
2003-01-17 17:34:33 +03:00
}
2004-08-30 19:56:23 +04:00
2008-08-15 16:01:06 +04:00
ikvm . runtime . Startup . setProperties ( props ) ;
2004-08-30 19:56:23 +04:00
2008-02-29 10:06:07 +03:00
// initialize the class library
java . lang . Thread . currentThread ( ) ;
2004-09-09 15:17:55 +04:00
* ( ( void * * ) ppvm ) = JavaVM . pJavaVM ;
return JavaVM . AttachCurrentThread ( JavaVM . pJavaVM , ( void * * ) ppenv , null ) ;
}
public static int GetDefaultJavaVMInitArgs ( void * vm_args )
2004-08-17 13:05:21 +04:00
{
2004-09-09 15:17:55 +04:00
// This is only used for JDK 1.1 JavaVMInitArgs, and we don't support those.
return JNIEnv . JNI_ERR ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
public static int GetCreatedJavaVMs ( void * ppvmBuf , int bufLen , int * nVMs )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
if ( jvmCreated )
{
if ( bufLen > = 1 )
{
* ( ( void * * ) ppvmBuf ) = JavaVM . pJavaVM ;
}
2005-06-28 11:12:28 +04:00
if ( nVMs ! = null )
{
* nVMs = 1 ;
}
2004-09-09 15:17:55 +04:00
}
2005-06-28 11:12:28 +04:00
else if ( nVMs ! = null )
2004-09-09 15:17:55 +04:00
{
* nVMs = 0 ;
}
return JNIEnv . JNI_OK ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
public unsafe struct Frame
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
private JNIEnv * pJNIEnv ;
2009-05-25 08:01:35 +04:00
private JNIEnv . ManagedJNIEnv env ;
2004-09-09 15:17:55 +04:00
private RuntimeMethodHandle prevMethod ;
private object [ ] quickLocals ;
private int quickLocalIndex ;
private int prevLocalRefSlot ;
2005-01-05 15:56:37 +03:00
internal ClassLoaderWrapper Enter ( ClassLoaderWrapper loader )
{
Enter ( new RuntimeMethodHandle ( ) ) ;
2009-05-25 08:01:35 +04:00
ClassLoaderWrapper prev = env . classLoader ;
env . classLoader = loader ;
2005-01-05 15:56:37 +03:00
return prev ;
}
internal void Leave ( ClassLoaderWrapper prev )
{
2009-05-25 08:01:35 +04:00
env . classLoader = prev ;
2005-03-17 17:27:18 +03:00
Leave ( ) ;
2005-01-05 15:56:37 +03:00
}
2004-09-09 15:17:55 +04:00
public IntPtr Enter ( RuntimeMethodHandle method )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
pJNIEnv = TlsHack . pJNIEnv ;
if ( pJNIEnv = = null )
{
pJNIEnv = JNIEnv . CreateJNIEnv ( ) ;
}
2009-05-25 08:01:35 +04:00
env = pJNIEnv - > GetManagedJNIEnv ( ) ;
prevMethod = env . currentMethod ;
env . currentMethod = method ;
object [ ] [ ] localRefs = env . localRefs ;
prevLocalRefSlot = env . localRefSlot ;
env . localRefSlot + + ;
if ( env . localRefSlot > = localRefs . Length )
2004-09-09 15:17:55 +04:00
{
object [ ] [ ] tmp = new object [ localRefs . Length * 2 ] [ ] ;
Array . Copy ( localRefs , 0 , tmp , 0 , localRefs . Length ) ;
2009-05-25 08:01:35 +04:00
env . localRefs = localRefs = tmp ;
2004-09-09 15:17:55 +04:00
}
2009-05-25 08:01:35 +04:00
if ( localRefs [ env . localRefSlot ] = = null )
2004-09-09 15:17:55 +04:00
{
2009-05-25 08:01:35 +04:00
localRefs [ env . localRefSlot ] = new object [ 32 ] ;
2004-09-09 15:17:55 +04:00
}
2009-05-25 08:01:35 +04:00
quickLocals = localRefs [ env . localRefSlot ] ;
quickLocalIndex = ( env . localRefSlot < < JNIEnv . LOCAL_REF_SHIFT ) ;
2004-09-09 15:17:55 +04:00
return ( IntPtr ) ( void * ) pJNIEnv ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
public void Leave ( )
2004-08-30 19:56:23 +04:00
{
2009-05-25 08:01:35 +04:00
env . currentMethod = prevMethod ;
Exception x = env . pendingException ;
env . pendingException = null ;
object [ ] [ ] localRefs = env . localRefs ;
while ( env . localRefSlot ! = prevLocalRefSlot )
2004-08-30 19:56:23 +04:00
{
2009-05-25 08:01:35 +04:00
if ( localRefs [ env . localRefSlot ] ! = null )
2004-08-30 19:56:23 +04:00
{
2009-05-25 08:01:35 +04:00
if ( localRefs [ env . localRefSlot ] . Length = = JNIEnv . LOCAL_REF_BUCKET_SIZE )
2004-09-09 15:17:55 +04:00
{
// if the bucket is totally allocated, we're assuming a leaky method so we throw the bucket away
2009-05-25 08:01:35 +04:00
localRefs [ env . localRefSlot ] = null ;
2004-09-09 15:17:55 +04:00
}
else
{
2009-05-25 08:01:35 +04:00
Array . Clear ( localRefs [ env . localRefSlot ] , 0 , localRefs [ env . localRefSlot ] . Length ) ;
2004-09-09 15:17:55 +04:00
}
2004-08-30 19:56:23 +04:00
}
2009-05-25 08:01:35 +04:00
env . localRefSlot - - ;
2004-09-09 15:17:55 +04:00
}
if ( x ! = null )
{
throw x ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
}
public static IntPtr GetFuncPtr ( RuntimeMethodHandle method , string clazz , string name , string sig )
{
MethodBase mb = MethodBase . GetMethodFromHandle ( method ) ;
ClassLoaderWrapper loader = ClassLoaderWrapper . GetWrapperFromType ( mb . DeclaringType ) . GetClassLoader ( ) ;
int sp = 0 ;
for ( int i = 1 ; sig [ i ] ! = ')' ; i + + )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
switch ( sig [ i ] )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
case '[' :
sp + = IntPtr . Size ;
2005-02-18 14:50:38 +03:00
while ( sig [ + + i ] = = '[' ) ;
2004-09-09 15:17:55 +04:00
if ( sig [ i ] = = 'L' )
{
2005-02-18 14:50:38 +03:00
while ( sig [ + + i ] ! = ';' ) ;
2004-09-09 15:17:55 +04:00
}
break ;
case 'L' :
sp + = IntPtr . Size ;
2005-02-18 14:50:38 +03:00
while ( sig [ + + i ] ! = ';' ) ;
2004-09-09 15:17:55 +04:00
break ;
case 'J' :
case 'D' :
sp + = 8 ;
break ;
case 'F' :
case 'I' :
case 'C' :
case 'Z' :
case 'S' :
case 'B' :
sp + = 4 ;
break ;
default :
Debug . Assert ( false ) ;
break ;
2004-08-30 19:56:23 +04:00
}
}
2005-02-18 14:50:38 +03:00
string mangledClass = JniMangle ( clazz ) ;
string mangledName = JniMangle ( name ) ;
string mangledSig = JniMangle ( sig . Substring ( 1 , sig . IndexOf ( ')' ) - 1 ) ) ;
string shortMethodName = String . Format ( "Java_{0}_{1}" , mangledClass , mangledName ) ;
string longMethodName = String . Format ( "Java_{0}_{1}__{2}" , mangledClass , mangledName , mangledSig ) ;
2005-02-23 15:56:15 +03:00
Tracer . Info ( Tracer . Jni , "Linking native method: {0}.{1}{2}, class loader = {3}, short = {4}, long = {5}, args = {6}" ,
clazz , name , sig , loader , shortMethodName , longMethodName , sp + 2 * IntPtr . Size ) ;
2004-09-09 15:17:55 +04:00
lock ( JniHelper . JniLock )
{
foreach ( IntPtr p in loader . GetNativeLibraries ( ) )
{
IntPtr pfunc = JniHelper . ikvm_GetProcAddress ( p , shortMethodName , sp + 2 * IntPtr . Size ) ;
if ( pfunc ! = IntPtr . Zero )
{
2005-02-23 15:56:15 +03:00
Tracer . Info ( Tracer . Jni , "Native method {0}.{1}{2} found in library 0x{3:X} (short)" , clazz , name , sig , p . ToInt64 ( ) ) ;
2004-09-09 15:17:55 +04:00
return pfunc ;
}
pfunc = JniHelper . ikvm_GetProcAddress ( p , longMethodName , sp + 2 * IntPtr . Size ) ;
if ( pfunc ! = IntPtr . Zero )
{
2005-02-23 15:56:15 +03:00
Tracer . Info ( Tracer . Jni , "Native method {0}.{1}{2} found in library 0x{3:X} (long)" , clazz , name , sig , p . ToInt64 ( ) ) ;
2004-09-09 15:17:55 +04:00
return pfunc ;
}
}
}
2007-04-23 12:24:33 +04:00
string msg = string . Format ( "{0}.{1}{2}" , clazz , name , sig ) ;
Tracer . Error ( Tracer . Jni , "UnsatisfiedLinkError: {0}" , msg ) ;
throw new java . lang . UnsatisfiedLinkError ( msg ) ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
2005-02-18 14:50:38 +03:00
private static string JniMangle ( string name )
{
StringBuilder sb = new StringBuilder ( ) ;
foreach ( char c in name )
{
if ( c = = '/' )
{
sb . Append ( '_' ) ;
}
else if ( c = = '_' )
{
sb . Append ( "_1" ) ;
}
else if ( c = = ';' )
{
sb . Append ( "_2" ) ;
}
else if ( c = = '[' )
{
sb . Append ( "_3" ) ;
}
else if ( ( c > = '0' & & c < = '9' ) | | ( c > = 'a' & & c < = 'z' ) | | ( c > = 'A' & & c < = 'Z' ) )
{
sb . Append ( c ) ;
}
else
{
sb . Append ( String . Format ( "_0{0:x4}" , ( int ) c ) ) ;
}
}
return sb . ToString ( ) ;
}
2004-09-09 15:17:55 +04:00
public IntPtr MakeLocalRef ( object obj )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
if ( obj = = null )
{
return IntPtr . Zero ;
}
int i = quickLocalIndex & JNIEnv . LOCAL_REF_MASK ;
if ( i < quickLocals . Length )
{
quickLocals [ i ] = obj ;
return ( IntPtr ) quickLocalIndex + + ;
}
else if ( i < JNIEnv . LOCAL_REF_BUCKET_SIZE )
{
object [ ] tmp = new object [ quickLocals . Length * 2 ] ;
Array . Copy ( quickLocals , 0 , tmp , 0 , quickLocals . Length ) ;
quickLocals = tmp ;
2009-05-25 08:01:35 +04:00
object [ ] [ ] localRefs = env . localRefs ;
localRefs [ env . localRefSlot ] = quickLocals ;
2004-09-09 15:17:55 +04:00
quickLocals [ i ] = obj ;
return ( IntPtr ) quickLocalIndex + + ;
}
else
{
// this can't happen, because LOCAL_REF_BUCKET_SIZE is larger than the maximum number of object
// references that can be required by a native method call (256 arguments + a class reference)
JVM . CriticalFailure ( "JNI.Frame.MakeLocalRef cannot spill into next slot" , null ) ;
return IntPtr . Zero ;
}
}
public object UnwrapLocalRef ( IntPtr p )
{
return pJNIEnv - > UnwrapRef ( p ) ;
2004-08-30 19:56:23 +04:00
}
}
}
2004-09-09 15:17:55 +04:00
sealed class JniHelper
{
[DllImport("ikvm-native")]
private static extern IntPtr ikvm_LoadLibrary ( string filename ) ;
[DllImport("ikvm-native")]
private static extern void ikvm_FreeLibrary ( IntPtr handle ) ;
[DllImport("ikvm-native")]
internal static extern IntPtr ikvm_GetProcAddress ( IntPtr handle , string name , int argc ) ;
[DllImport("ikvm-native")]
private unsafe static extern int ikvm_CallOnLoad ( IntPtr method , void * jvm , void * reserved ) ;
[DllImport("ikvm-native")]
internal unsafe static extern void * * ikvm_GetJNIEnvVTable ( ) ;
[DllImport("ikvm-native")]
internal unsafe static extern void * ikvm_MarshalDelegate ( Delegate d ) ;
2008-08-15 16:01:06 +04:00
private static List < IntPtr > nativeLibraries = new List < IntPtr > ( ) ;
2004-09-09 15:17:55 +04:00
internal static readonly object JniLock = new object ( ) ;
2008-05-20 11:36:50 +04:00
// MONOBUG with mcs we can't pass ClassLoaderWrapper from IKVM.Runtime.dll to IKVM.Runtime.JNI.dll
2009-03-09 12:01:36 +03:00
internal unsafe static long LoadLibrary ( string filename , object loader )
2008-05-20 11:36:50 +04:00
{
return LoadLibrary ( filename , ( ClassLoaderWrapper ) loader ) ;
}
2009-03-09 12:01:36 +03:00
// MONOBUG with mcs we can't pass ClassLoaderWrapper from IKVM.Runtime.dll to IKVM.Runtime.JNI.dll
internal static void UnloadLibrary ( long handle , object loader )
{
UnloadLibrary ( handle , ( ClassLoaderWrapper ) loader ) ;
}
private unsafe static long LoadLibrary ( string filename , ClassLoaderWrapper loader )
2004-08-30 19:56:23 +04:00
{
2005-02-23 15:56:15 +03:00
Tracer . Info ( Tracer . Jni , "loadLibrary: {0}, class loader: {1}" , filename , loader ) ;
2004-09-09 15:17:55 +04:00
lock ( JniLock )
{
IntPtr p = ikvm_LoadLibrary ( filename ) ;
if ( p = = IntPtr . Zero )
{
2005-02-23 15:56:15 +03:00
Tracer . Info ( Tracer . Jni , "Library not found: {0}" , filename ) ;
2004-09-09 15:17:55 +04:00
return 0 ;
}
try
{
foreach ( IntPtr tmp in loader . GetNativeLibraries ( ) )
{
if ( tmp = = p )
{
// the library was already loaded by the current class loader,
// no need to do anything
ikvm_FreeLibrary ( p ) ;
2005-02-23 15:56:15 +03:00
Tracer . Warning ( Tracer . Jni , "Library was already loaded: {0}" , filename ) ;
2009-03-09 12:01:36 +03:00
return p . ToInt64 ( ) ;
2004-09-09 15:17:55 +04:00
}
}
if ( nativeLibraries . Contains ( p ) )
{
2007-04-23 12:24:33 +04:00
string msg = string . Format ( "Native library {0} already loaded in another classloader" , filename ) ;
Tracer . Error ( Tracer . Jni , "UnsatisfiedLinkError: {0}" , msg ) ;
throw new java . lang . UnsatisfiedLinkError ( msg ) ;
2004-09-09 15:17:55 +04:00
}
2005-02-23 15:56:15 +03:00
Tracer . Info ( Tracer . Jni , "Library loaded: {0}, handle = 0x{1:X}" , filename , p . ToInt64 ( ) ) ;
2004-09-09 15:17:55 +04:00
IntPtr onload = ikvm_GetProcAddress ( p , "JNI_OnLoad" , IntPtr . Size * 2 ) ;
if ( onload ! = IntPtr . Zero )
{
2005-02-23 15:56:15 +03:00
Tracer . Info ( Tracer . Jni , "Calling JNI_OnLoad on: {0}" , filename ) ;
2004-09-09 15:17:55 +04:00
JNI . Frame f = new JNI . Frame ( ) ;
2005-03-17 17:27:18 +03:00
int version ;
2005-01-05 15:56:37 +03:00
ClassLoaderWrapper prevLoader = f . Enter ( loader ) ;
2005-03-17 17:27:18 +03:00
try
{
2007-11-26 11:38:38 +03:00
// TODO on Whidbey we should be able to use Marshal.GetDelegateForFunctionPointer to call OnLoad
2005-03-17 17:27:18 +03:00
version = ikvm_CallOnLoad ( onload , JavaVM . pJavaVM , null ) ;
2006-10-19 10:12:48 +04:00
Tracer . Info ( Tracer . Jni , "JNI_OnLoad returned: 0x{0:X8}" , version ) ;
2005-03-17 17:27:18 +03:00
}
finally
{
f . Leave ( prevLoader ) ;
}
2005-02-02 18:11:26 +03:00
if ( ! JNI . IsSupportedJniVersion ( version ) )
2004-09-09 15:17:55 +04:00
{
2007-04-23 12:24:33 +04:00
string msg = string . Format ( "Unsupported JNI version 0x{0:X} required by {1}" , version , filename ) ;
Tracer . Error ( Tracer . Jni , "UnsatisfiedLinkError: {0}" , msg ) ;
throw new java . lang . UnsatisfiedLinkError ( msg ) ;
2004-09-09 15:17:55 +04:00
}
}
nativeLibraries . Add ( p ) ;
loader . RegisterNativeLibrary ( p ) ;
2009-03-09 12:01:36 +03:00
return p . ToInt64 ( ) ;
2004-09-09 15:17:55 +04:00
}
catch
{
ikvm_FreeLibrary ( p ) ;
throw ;
}
2004-08-30 19:56:23 +04:00
}
}
2009-03-09 12:01:36 +03:00
private unsafe static void UnloadLibrary ( long handle , ClassLoaderWrapper loader )
{
lock ( JniLock )
{
Tracer . Info ( Tracer . Jni , "Unloading library: handle = 0x{0:X}, class loader = {1}" , handle , loader ) ;
IntPtr p = ( IntPtr ) handle ;
IntPtr onunload = ikvm_GetProcAddress ( p , "JNI_OnUnload" , IntPtr . Size * 2 ) ;
if ( onunload ! = IntPtr . Zero )
{
Tracer . Info ( Tracer . Jni , "Calling JNI_OnUnload on: handle = 0x{0:X}" , handle ) ;
JNI . Frame f = new JNI . Frame ( ) ;
ClassLoaderWrapper prevLoader = f . Enter ( loader ) ;
try
{
// TODO on Whidbey we should be able to use Marshal.GetDelegateForFunctionPointer to call OnLoad
ikvm_CallOnLoad ( onunload , JavaVM . pJavaVM , null ) ;
}
finally
{
f . Leave ( prevLoader ) ;
}
}
nativeLibraries . Remove ( p ) ;
loader . UnregisterNativeLibrary ( p ) ;
ikvm_FreeLibrary ( ( IntPtr ) handle ) ;
}
}
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
class GlobalRefs
{
internal static System . Collections . ArrayList globalRefs = new System . Collections . ArrayList ( ) ;
internal static readonly object weakRefLock = new object ( ) ;
internal static GCHandle [ ] weakRefs = new GCHandle [ 16 ] ;
}
unsafe class VtableBuilder
{
2007-11-26 11:38:38 +03:00
// TODO on Whidbey we should use generics to cut down on the number of delegates needed
2004-09-09 15:17:55 +04:00
delegate int pf_int_IntPtr ( JNIEnv * pEnv , IntPtr p ) ;
delegate IntPtr pf_IntPtr_IntPtr ( JNIEnv * pEnv , IntPtr p ) ;
delegate void pf_void_IntPtr ( JNIEnv * pEnv , IntPtr p ) ;
delegate IntPtr pf_IntPtr ( JNIEnv * pEnv ) ;
delegate void pf_void ( JNIEnv * pEnv ) ;
delegate sbyte pf_sbyte ( JNIEnv * pEnv ) ;
delegate IntPtr pf_IntPtr_pbyte ( JNIEnv * pEnv , byte * p ) ;
delegate int pf_int ( JNIEnv * pEnv ) ;
delegate IntPtr pf_IntPtr_pbyte_IntPtr_psbyte_IntPtr ( JNIEnv * pEnv , byte * p1 , IntPtr p2 , sbyte * p3 , int p4 ) ;
delegate IntPtr pf_IntPtr_IntPtr_IntPtr ( JNIEnv * pEnv , IntPtr p1 , IntPtr p2 ) ;
delegate jchar * pf_pjchar_IntPtr_pjboolean ( JNIEnv * pEnv , IntPtr p1 , jboolean * p2 ) ;
2005-09-01 11:34:53 +04:00
delegate void pf_void_IntPtr_pvoid_int ( JNIEnv * pEnv , IntPtr p1 , void * p2 , int p3 ) ;
delegate void * pf_pvoid_IntPtr_pjboolean ( JNIEnv * pEnv , IntPtr p1 , jboolean * p2 ) ;
2004-09-09 15:17:55 +04:00
delegate int pf_int_IntPtr_pbyte ( JNIEnv * pEnv , IntPtr p1 , byte * p2 ) ;
delegate void pf_void_pbyte ( JNIEnv * pEnv , byte * p1 ) ;
delegate IntPtr pf_IntPtr_IntPtr_pbyte_pbyte ( JNIEnv * pEnv , IntPtr p1 , byte * p2 , byte * p3 ) ;
delegate int pf_int_IntPtr_pJNINativeMethod_int ( JNIEnv * pEnv , IntPtr p1 , JNIEnv . JNINativeMethod * p2 , int p3 ) ;
delegate int pf_int_ppJavaVM ( JNIEnv * pEnv , JavaVM * * ppJavaVM ) ;
delegate sbyte pf_sbyte_IntPtr_IntPtr ( JNIEnv * pEnv , IntPtr p1 , IntPtr p2 ) ;
delegate short pf_short_IntPtr_IntPtr ( JNIEnv * pEnv , IntPtr p1 , IntPtr p2 ) ;
delegate ushort pf_ushort_IntPtr_IntPtr ( JNIEnv * pEnv , IntPtr p1 , IntPtr p2 ) ;
delegate int pf_int_IntPtr_IntPtr ( JNIEnv * pEnv , IntPtr p1 , IntPtr p2 ) ;
delegate long pf_long_IntPtr_IntPtr ( JNIEnv * pEnv , IntPtr p1 , IntPtr p2 ) ;
delegate float pf_float_IntPtr_IntPtr ( JNIEnv * pEnv , IntPtr p1 , IntPtr p2 ) ;
delegate double pf_double_IntPtr_IntPtr ( JNIEnv * pEnv , IntPtr p1 , IntPtr p2 ) ;
delegate void pf_void_IntPtr_IntPtr_IntPtr ( JNIEnv * pEnv , IntPtr p1 , IntPtr p2 , IntPtr p3 ) ;
delegate void pf_void_IntPtr_IntPtr_sbyte ( JNIEnv * pEnv , IntPtr p1 , IntPtr p2 , sbyte p3 ) ;
delegate void pf_void_IntPtr_IntPtr_short ( JNIEnv * pEnv , IntPtr p1 , IntPtr p2 , short p3 ) ;
delegate void pf_void_IntPtr_IntPtr_ushort ( JNIEnv * pEnv , IntPtr p1 , IntPtr p2 , ushort p3 ) ;
delegate void pf_void_IntPtr_IntPtr_int ( JNIEnv * pEnv , IntPtr p1 , IntPtr p2 , int p3 ) ;
delegate void pf_void_IntPtr_IntPtr_long ( JNIEnv * pEnv , IntPtr p1 , IntPtr p2 , long p3 ) ;
delegate void pf_void_IntPtr_IntPtr_float ( JNIEnv * pEnv , IntPtr p1 , IntPtr p2 , float p3 ) ;
delegate void pf_void_IntPtr_IntPtr_double ( JNIEnv * pEnv , IntPtr p1 , IntPtr p2 , double p3 ) ;
delegate IntPtr pf_IntPtr_pjchar_int ( JNIEnv * pEnv , jchar * p1 , int p2 ) ;
delegate void pf_void_IntPtr_IntPtr ( JNIEnv * pEnv , IntPtr p1 , IntPtr p2 ) ;
delegate void pf_void_IntPtr_pjchar ( JNIEnv * pEnv , IntPtr p1 , jchar * p2 ) ;
delegate IntPtr pf_IntPtr_int_IntPtr_IntPtr ( JNIEnv * pEnv , int p1 , IntPtr p2 , IntPtr p3 ) ;
delegate IntPtr pf_IntPtr_IntPtr_int ( JNIEnv * pEnv , IntPtr p1 , int p2 ) ;
delegate void pf_void_IntPtr_int_IntPtr ( JNIEnv * pEnv , IntPtr p1 , int p2 , IntPtr p3 ) ;
delegate IntPtr pf_IntPtr_int ( JNIEnv * pEnv , int p1 ) ;
delegate void pf_void_IntPtr_int_int_IntPtr ( JNIEnv * pEnv , IntPtr p1 , int p2 , int p3 , IntPtr p4 ) ;
delegate IntPtr pf_IntPtr_IntPtr_IntPtr_pjvalue ( JNIEnv * pEnv , IntPtr p1 , IntPtr p2 , JNIEnv . jvalue * p3 ) ;
delegate sbyte pf_sbyte_IntPtr_IntPtr_pjvalue ( JNIEnv * pEnv , IntPtr p1 , IntPtr p2 , JNIEnv . jvalue * p3 ) ;
delegate short pf_short_IntPtr_IntPtr_pjvalue ( JNIEnv * pEnv , IntPtr p1 , IntPtr p2 , JNIEnv . jvalue * p3 ) ;
delegate ushort pf_ushort_IntPtr_IntPtr_pjvalue ( JNIEnv * pEnv , IntPtr p1 , IntPtr p2 , JNIEnv . jvalue * p3 ) ;
delegate int pf_int_IntPtr_IntPtr_pjvalue ( JNIEnv * pEnv , IntPtr p1 , IntPtr p2 , JNIEnv . jvalue * p3 ) ;
delegate long pf_long_IntPtr_IntPtr_pjvalue ( JNIEnv * pEnv , IntPtr p1 , IntPtr p2 , JNIEnv . jvalue * p3 ) ;
delegate float pf_float_IntPtr_IntPtr_pjvalue ( JNIEnv * pEnv , IntPtr p1 , IntPtr p2 , JNIEnv . jvalue * p3 ) ;
delegate double pf_double_IntPtr_IntPtr_pjvalue ( JNIEnv * pEnv , IntPtr p1 , IntPtr p2 , JNIEnv . jvalue * p3 ) ;
delegate void pf_void_IntPtr_IntPtr_pjvalue ( JNIEnv * pEnv , IntPtr p1 , IntPtr p2 , JNIEnv . jvalue * p3 ) ;
delegate IntPtr pf_IntPtr_IntPtr_IntPtr_IntPtr_pjvalue ( JNIEnv * pEnv , IntPtr p1 , IntPtr p2 , IntPtr p3 , JNIEnv . jvalue * p4 ) ;
delegate sbyte pf_sbyte_IntPtr_IntPtr_IntPtr_pjvalue ( JNIEnv * pEnv , IntPtr p1 , IntPtr p2 , IntPtr p3 , JNIEnv . jvalue * p4 ) ;
delegate ushort pf_ushort_IntPtr_IntPtr_IntPtr_pjvalue ( JNIEnv * pEnv , IntPtr p1 , IntPtr p2 , IntPtr p3 , JNIEnv . jvalue * p4 ) ;
delegate short pf_short_IntPtr_IntPtr_IntPtr_pjvalue ( JNIEnv * pEnv , IntPtr p1 , IntPtr p2 , IntPtr p3 , JNIEnv . jvalue * p4 ) ;
delegate int pf_int_IntPtr_IntPtr_IntPtr_pjvalue ( JNIEnv * pEnv , IntPtr p1 , IntPtr p2 , IntPtr p3 , JNIEnv . jvalue * p4 ) ;
delegate long pf_long_IntPtr_IntPtr_IntPtr_pjvalue ( JNIEnv * pEnv , IntPtr p1 , IntPtr p2 , IntPtr p3 , JNIEnv . jvalue * p4 ) ;
delegate float pf_float_IntPtr_IntPtr_IntPtr_pjvalue ( JNIEnv * pEnv , IntPtr p1 , IntPtr p2 , IntPtr p3 , JNIEnv . jvalue * p4 ) ;
delegate double pf_double_IntPtr_IntPtr_IntPtr_pjvalue ( JNIEnv * pEnv , IntPtr p1 , IntPtr p2 , IntPtr p3 , JNIEnv . jvalue * p4 ) ;
delegate void pf_void_IntPtr_IntPtr_IntPtr_pjvalue ( JNIEnv * pEnv , IntPtr p1 , IntPtr p2 , IntPtr p3 , JNIEnv . jvalue * p4 ) ;
delegate byte * pf_pbyte_IntPtr_pjboolean ( JNIEnv * pEnv , IntPtr p1 , jboolean * p2 ) ;
delegate void pf_void_IntPtr_pbyte ( JNIEnv * pEnv , IntPtr p1 , byte * p2 ) ;
delegate jboolean * pf_pjboolean_IntPtr_pjboolean ( JNIEnv * pEnv , IntPtr p1 , jboolean * p2 ) ;
delegate jbyte * pf_pjbyte_IntPtr_pjboolean ( JNIEnv * pEnv , IntPtr p1 , jboolean * p2 ) ;
delegate jshort * pf_pjshort_IntPtr_pjboolean ( JNIEnv * pEnv , IntPtr p1 , jboolean * p2 ) ;
delegate jint * pf_pjint_IntPtr_pjboolean ( JNIEnv * pEnv , IntPtr p1 , jboolean * p2 ) ;
delegate jlong * pf_pjlong_IntPtr_pjboolean ( JNIEnv * pEnv , IntPtr p1 , jboolean * p2 ) ;
delegate jfloat * pf_pjfloat_IntPtr_pjboolean ( JNIEnv * pEnv , IntPtr p1 , jboolean * p2 ) ;
delegate jdouble * pf_pjdouble_IntPtr_pjboolean ( JNIEnv * pEnv , IntPtr p1 , jboolean * p2 ) ;
delegate void pf_void_IntPtr_pjboolean_int ( JNIEnv * pEnv , IntPtr p1 , jboolean * p2 , int p3 ) ;
delegate void pf_void_IntPtr_pjbyte_int ( JNIEnv * pEnv , IntPtr p1 , jbyte * p2 , int p3 ) ;
delegate void pf_void_IntPtr_pjchar_int ( JNIEnv * pEnv , IntPtr p1 , jchar * p2 , int p3 ) ;
delegate void pf_void_IntPtr_pjshort_int ( JNIEnv * pEnv , IntPtr p1 , jshort * p2 , int p3 ) ;
delegate void pf_void_IntPtr_pjint_int ( JNIEnv * pEnv , IntPtr p1 , jint * p2 , int p3 ) ;
delegate void pf_void_IntPtr_pjlong_int ( JNIEnv * pEnv , IntPtr p1 , jlong * p2 , int p3 ) ;
delegate void pf_void_IntPtr_pjfloat_int ( JNIEnv * pEnv , IntPtr p1 , jfloat * p2 , int p3 ) ;
delegate void pf_void_IntPtr_pjdouble_int ( JNIEnv * pEnv , IntPtr p1 , jdouble * p2 , int p3 ) ;
delegate int pf_int_int ( JNIEnv * pEnv , int p1 ) ;
2004-11-23 20:46:39 +03:00
delegate IntPtr pf_IntPtr_IntPtr_long ( JNIEnv * pEnv , IntPtr p1 , long p2 ) ;
delegate long pf_long_IntPtr ( JNIEnv * pEnv , IntPtr p1 ) ;
2005-05-17 17:18:16 +04:00
delegate IntPtr pf_IntPtr_IntPtr_IntPtr_sbyte ( JNIEnv * pEnv , IntPtr p1 , IntPtr p2 , sbyte p3 ) ;
2004-09-09 15:17:55 +04:00
internal static void * vtable ;
static VtableBuilder ( )
{
2005-02-23 15:56:15 +03:00
JNI . jvmCreated = true ;
2004-09-09 15:17:55 +04:00
// JNIEnv
void * * pmcpp = JniHelper . ikvm_GetJNIEnvVTable ( ) ;
void * * p = ( void * * ) JniMem . Alloc ( IntPtr . Size * vtableDelegates . Length ) ;
for ( int i = 0 ; i < vtableDelegates . Length ; i + + )
{
if ( vtableDelegates [ i ] ! = null )
{
2007-11-26 11:38:38 +03:00
// TODO on Whidbey we can use Marshal.GetFunctionPointerForDelegate
2004-09-09 15:17:55 +04:00
p [ i ] = JniHelper . ikvm_MarshalDelegate ( vtableDelegates [ i ] ) ;
}
else
{
p [ i ] = pmcpp [ i ] ;
}
}
vtable = p ;
}
static Delegate [ ] vtableDelegates =
2004-08-30 19:56:23 +04:00
{
new pf_int_IntPtr_pbyte ( JNIEnv . GetMethodArgs ) , //virtual void JNICALL reserved0();
null , //virtual void JNICALL reserved1();
null , //virtual void JNICALL reserved2();
null , //virtual void JNICALL reserved3();
new pf_int ( JNIEnv . GetVersion ) , //virtual jint JNICALL GetVersion();
2004-09-05 13:37:58 +04:00
new pf_IntPtr_pbyte_IntPtr_psbyte_IntPtr ( JNIEnv . DefineClass ) , //virtual jclass JNICALL DefineClass(const char *name, jobject loader, const jbyte *buf, jsize len);
2004-08-30 19:56:23 +04:00
new pf_IntPtr_pbyte ( JNIEnv . FindClass ) , //virtual jclass JNICALL FindClass(const char *name);
new pf_IntPtr_IntPtr ( JNIEnv . FromReflectedMethod ) , //virtual jmethodID JNICALL FromReflectedMethod(jobject method);
new pf_IntPtr_IntPtr ( JNIEnv . FromReflectedField ) , //virtual jfieldID JNICALL FromReflectedField(jobject field);
2005-05-17 17:18:16 +04:00
new pf_IntPtr_IntPtr_IntPtr_sbyte ( JNIEnv . ToReflectedMethod ) , //virtual jobject JNICALL ToReflectedMethod(jclass clazz, jmethodID methodID, jboolean isStatic);
2004-08-30 19:56:23 +04:00
new pf_IntPtr_IntPtr ( JNIEnv . GetSuperclass ) , //virtual jclass JNICALL GetSuperclass(jclass sub);
new pf_sbyte_IntPtr_IntPtr ( JNIEnv . IsAssignableFrom ) , //virtual jboolean JNICALL IsAssignableFrom(jclass sub, jclass sup);
2005-05-17 17:18:16 +04:00
new pf_IntPtr_IntPtr_IntPtr_sbyte ( JNIEnv . ToReflectedField ) , //virtual jobject JNICALL ToReflectedField(jclass clazz, jfieldID fieldID, jboolean isStatic);
2004-08-30 19:56:23 +04:00
new pf_int_IntPtr ( JNIEnv . Throw ) , //virtual jint JNICALL Throw(jthrowable obj);
new pf_int_IntPtr_pbyte ( JNIEnv . ThrowNew ) , //virtual jint JNICALL ThrowNew(jclass clazz, const char *msg);
new pf_IntPtr ( JNIEnv . ExceptionOccurred ) , //virtual jthrowable JNICALL ExceptionOccurred();
new pf_void ( JNIEnv . ExceptionDescribe ) , //virtual void JNICALL ExceptionDescribe();
new pf_void ( JNIEnv . ExceptionClear ) , //virtual void JNICALL ExceptionClear();
new pf_void_pbyte ( JNIEnv . FatalError ) , //virtual void JNICALL FatalError(const char *msg);
2004-09-05 13:37:58 +04:00
new pf_int_int ( JNIEnv . PushLocalFrame ) , //virtual jint JNICALL PushLocalFrame(jint capacity);
new pf_IntPtr_IntPtr ( JNIEnv . PopLocalFrame ) , //virtual jobject JNICALL PopLocalFrame(jobject result);
2004-08-30 19:56:23 +04:00
new pf_IntPtr_IntPtr ( JNIEnv . NewGlobalRef ) , //virtual jobject JNICALL NewGlobalRef(jobject lobj);
new pf_void_IntPtr ( JNIEnv . DeleteGlobalRef ) , //virtual void JNICALL DeleteGlobalRef(jobject gref);
new pf_void_IntPtr ( JNIEnv . DeleteLocalRef ) , //virtual void JNICALL DeleteLocalRef(jobject obj);
new pf_sbyte_IntPtr_IntPtr ( JNIEnv . IsSameObject ) , //virtual jboolean JNICALL IsSameObject(jobject obj1, jobject obj2);
new pf_IntPtr_IntPtr ( JNIEnv . NewLocalRef ) , //virtual jobject JNICALL NewLocalRef(jobject ref);
2004-09-05 13:37:58 +04:00
new pf_int_int ( JNIEnv . EnsureLocalCapacity ) , //virtual jint JNICALL EnsureLocalCapacity(jint capacity);
2004-08-30 19:56:23 +04:00
new pf_IntPtr_IntPtr ( JNIEnv . AllocObject ) , //virtual jobject JNICALL AllocObject(jclass clazz);
null , //virtual jobject JNICALL NewObject(jclass clazz, jmethodID methodID, ...);
null , //virtual jobject JNICALL NewObjectV(jclass clazz, jmethodID methodID, va_list args);
new pf_IntPtr_IntPtr_IntPtr_pjvalue ( JNIEnv . NewObjectA ) , //virtual jobject JNICALL NewObjectA(jclass clazz, jmethodID methodID, jvalue *args);
new pf_IntPtr_IntPtr ( JNIEnv . GetObjectClass ) , //virtual jclass JNICALL GetObjectClass(jobject obj);
new pf_sbyte_IntPtr_IntPtr ( JNIEnv . IsInstanceOf ) , //virtual jboolean JNICALL IsInstanceOf(jobject obj, jclass clazz);
new pf_IntPtr_IntPtr_pbyte_pbyte ( JNIEnv . GetMethodID ) , //virtual jmethodID JNICALL GetMethodID(jclass clazz, const char *name, const char *sig);
null , //virtual jobject JNICALL CallObjectMethod(jobject obj, jmethodID methodID, ...);
null , //virtual jobject JNICALL CallObjectMethodV(jobject obj, jmethodID methodID, va_list args);
new pf_IntPtr_IntPtr_IntPtr_pjvalue ( JNIEnv . CallObjectMethodA ) , //virtual jobject JNICALL CallObjectMethodA(jobject obj, jmethodID methodID, jvalue * args);
null , //virtual jboolean JNICALL CallBooleanMethod(jobject obj, jmethodID methodID, ...);
null , //virtual jboolean JNICALL CallBooleanMethodV(jobject obj, jmethodID methodID, va_list args);
new pf_sbyte_IntPtr_IntPtr_pjvalue ( JNIEnv . CallBooleanMethodA ) , //virtual jboolean JNICALL CallBooleanMethodA(jobject obj, jmethodID methodID, jvalue * args);
null , //virtual jbyte JNICALL CallByteMethod(jobject obj, jmethodID methodID, ...);
null , //virtual jbyte JNICALL CallByteMethodV(jobject obj, jmethodID methodID, va_list args);
new pf_sbyte_IntPtr_IntPtr_pjvalue ( JNIEnv . CallByteMethodA ) , //virtual jbyte JNICALL CallByteMethodA(jobject obj, jmethodID methodID, jvalue *args);
null , //virtual jchar JNICALL CallCharMethod(jobject obj, jmethodID methodID, ...);
null , //virtual jchar JNICALL CallCharMethodV(jobject obj, jmethodID methodID, va_list args);
2004-09-05 13:37:58 +04:00
new pf_ushort_IntPtr_IntPtr_pjvalue ( JNIEnv . CallCharMethodA ) , //virtual jchar JNICALL CallCharMethodA(jobject obj, jmethodID methodID, jvalue *args);
2004-08-30 19:56:23 +04:00
null , //virtual jshort JNICALL CallShortMethod(jobject obj, jmethodID methodID, ...);
null , //virtual jshort JNICALL CallShortMethodV(jobject obj, jmethodID methodID, va_list args);
new pf_short_IntPtr_IntPtr_pjvalue ( JNIEnv . CallShortMethodA ) , //virtual jshort JNICALL CallShortMethodA(jobject obj, jmethodID methodID, jvalue *args);
null , //virtual jint JNICALL CallIntMethod(jobject obj, jmethodID methodID, ...);
null , //virtual jint JNICALL CallIntMethodV(jobject obj, jmethodID methodID, va_list args);
new pf_int_IntPtr_IntPtr_pjvalue ( JNIEnv . CallIntMethodA ) , //virtual jint JNICALL CallIntMethodA(jobject obj, jmethodID methodID, jvalue *args);
null , //virtual jlong JNICALL CallLongMethod(jobject obj, jmethodID methodID, ...);
null , //virtual jlong JNICALL CallLongMethodV(jobject obj, jmethodID methodID, va_list args);
new pf_long_IntPtr_IntPtr_pjvalue ( JNIEnv . CallLongMethodA ) , //virtual jlong JNICALL CallLongMethodA(jobject obj, jmethodID methodID, jvalue *args);
null , //virtual jfloat JNICALL CallFloatMethod(jobject obj, jmethodID methodID, ...);
null , //virtual jfloat JNICALL CallFloatMethodV(jobject obj, jmethodID methodID, va_list args);
new pf_float_IntPtr_IntPtr_pjvalue ( JNIEnv . CallFloatMethodA ) , //virtual jfloat JNICALL CallFloatMethodA(jobject obj, jmethodID methodID, jvalue *args);
null , //virtual jdouble JNICALL CallDoubleMethod(jobject obj, jmethodID methodID, ...);
null , //virtual jdouble JNICALL CallDoubleMethodV(jobject obj, jmethodID methodID, va_list args);
new pf_double_IntPtr_IntPtr_pjvalue ( JNIEnv . CallDoubleMethodA ) , //virtual jdouble JNICALL CallDoubleMethodA(jobject obj, jmethodID methodID, jvalue *args);
null , //virtual void JNICALL CallVoidMethod(jobject obj, jmethodID methodID, ...);
null , //virtual void JNICALL CallVoidMethodV(jobject obj, jmethodID methodID, va_list args);
new pf_void_IntPtr_IntPtr_pjvalue ( JNIEnv . CallVoidMethodA ) , //virtual void JNICALL CallVoidMethodA(jobject obj, jmethodID methodID, jvalue * args);
null , //virtual jobject JNICALL CallNonvirtualObjectMethod(jobject obj, jclass clazz, jmethodID methodID, ...);
null , //virtual jobject JNICALL CallNonvirtualObjectMethodV(jobject obj, jclass clazz, jmethodID methodID, va_list args);
new pf_IntPtr_IntPtr_IntPtr_IntPtr_pjvalue ( JNIEnv . CallNonvirtualObjectMethodA ) , //virtual jobject JNICALL CallNonvirtualObjectMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue * args);
null , //virtual jboolean JNICALL CallNonvirtualBooleanMethod(jobject obj, jclass clazz, jmethodID methodID, ...);
null , //virtual jboolean JNICALL CallNonvirtualBooleanMethodV(jobject obj, jclass clazz, jmethodID methodID, va_list args);
new pf_sbyte_IntPtr_IntPtr_IntPtr_pjvalue ( JNIEnv . CallNonvirtualBooleanMethodA ) , //virtual jboolean JNICALL CallNonvirtualBooleanMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue * args);
null , //virtual jbyte JNICALL CallNonvirtualByteMethod(jobject obj, jclass clazz, jmethodID methodID, ...);
null , //virtual jbyte JNICALL CallNonvirtualByteMethodV(jobject obj, jclass clazz, jmethodID methodID, va_list args);
new pf_sbyte_IntPtr_IntPtr_IntPtr_pjvalue ( JNIEnv . CallNonvirtualByteMethodA ) , //virtual jbyte JNICALL CallNonvirtualByteMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue *args);
null , //virtual jchar JNICALL CallNonvirtualCharMethod(jobject obj, jclass clazz, jmethodID methodID, ...);
null , //virtual jchar JNICALL CallNonvirtualCharMethodV(jobject obj, jclass clazz, jmethodID methodID, va_list args);
2004-09-05 13:37:58 +04:00
new pf_ushort_IntPtr_IntPtr_IntPtr_pjvalue ( JNIEnv . CallNonvirtualCharMethodA ) , //virtual jchar JNICALL CallNonvirtualCharMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue *args);
2004-08-30 19:56:23 +04:00
null , //virtual jshort JNICALL CallNonvirtualShortMethod(jobject obj, jclass clazz, jmethodID methodID, ...);
null , //virtual jshort JNICALL CallNonvirtualShortMethodV(jobject obj, jclass clazz, jmethodID methodID, va_list args);
new pf_short_IntPtr_IntPtr_IntPtr_pjvalue ( JNIEnv . CallNonvirtualShortMethodA ) , //virtual jshort JNICALL CallNonvirtualShortMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue *args);
null , //virtual jint JNICALL CallNonvirtualIntMethod(jobject obj, jclass clazz, jmethodID methodID, ...);
null , //virtual jint JNICALL CallNonvirtualIntMethodV(jobject obj, jclass clazz, jmethodID methodID, va_list args);
new pf_int_IntPtr_IntPtr_IntPtr_pjvalue ( JNIEnv . CallNonvirtualIntMethodA ) , //virtual jint JNICALL CallNonvirtualIntMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue *args);
null , //virtual jlong JNICALL CallNonvirtualLongMethod(jobject obj, jclass clazz, jmethodID methodID, ...);
null , //virtual jlong JNICALL CallNonvirtualLongMethodV(jobject obj, jclass clazz, jmethodID methodID, va_list args);
new pf_long_IntPtr_IntPtr_IntPtr_pjvalue ( JNIEnv . CallNonvirtualLongMethodA ) , //virtual jlong JNICALL CallNonvirtualLongMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue *args);
null , //virtual jfloat JNICALL CallNonvirtualFloatMethod(jobject obj, jclass clazz, jmethodID methodID, ...);
null , //virtual jfloat JNICALL CallNonvirtualFloatMethodV(jobject obj, jclass clazz, jmethodID methodID, va_list args);
new pf_float_IntPtr_IntPtr_IntPtr_pjvalue ( JNIEnv . CallNonvirtualFloatMethodA ) , //virtual jfloat JNICALL CallNonvirtualFloatMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue *args);
null , //virtual jdouble JNICALL CallNonvirtualDoubleMethod(jobject obj, jclass clazz, jmethodID methodID, ...);
null , //virtual jdouble JNICALL CallNonvirtualDoubleMethodV(jobject obj, jclass clazz, jmethodID methodID, va_list args);
new pf_double_IntPtr_IntPtr_IntPtr_pjvalue ( JNIEnv . CallNonvirtualDoubleMethodA ) , //virtual jdouble JNICALL CallNonvirtualDoubleMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue *args);
null , //virtual void JNICALL CallNonvirtualVoidMethod(jobject obj, jclass clazz, jmethodID methodID, ...);
null , //virtual void JNICALL CallNonvirtualVoidMethodV(jobject obj, jclass clazz, jmethodID methodID, va_list args);
new pf_void_IntPtr_IntPtr_IntPtr_pjvalue ( JNIEnv . CallNonvirtualVoidMethodA ) , //virtual void JNICALL CallNonvirtualVoidMethodA(jobject obj, jclass clazz, jmethodID methodID, jvalue * args);
new pf_IntPtr_IntPtr_pbyte_pbyte ( JNIEnv . GetFieldID ) , //virtual jfieldID JNICALL GetFieldID(jclass clazz, const char *name, const char *sig);
new pf_IntPtr_IntPtr_IntPtr ( JNIEnv . GetObjectField ) , //virtual jobject JNICALL GetObjectField(jobject obj, jfieldID fieldID);
new pf_sbyte_IntPtr_IntPtr ( JNIEnv . GetBooleanField ) , //virtual jboolean JNICALL GetBooleanField(jobject obj, jfieldID fieldID);
new pf_sbyte_IntPtr_IntPtr ( JNIEnv . GetByteField ) , //virtual jbyte JNICALL GetByteField(jobject obj, jfieldID fieldID);
2004-09-05 13:37:58 +04:00
new pf_ushort_IntPtr_IntPtr ( JNIEnv . GetCharField ) , //virtual jchar JNICALL GetCharField(jobject obj, jfieldID fieldID);
2004-08-30 19:56:23 +04:00
new pf_short_IntPtr_IntPtr ( JNIEnv . GetShortField ) , //virtual jshort JNICALL GetShortField(jobject obj, jfieldID fieldID);
new pf_int_IntPtr_IntPtr ( JNIEnv . GetIntField ) , //virtual jint JNICALL GetIntField(jobject obj, jfieldID fieldID);
new pf_long_IntPtr_IntPtr ( JNIEnv . GetLongField ) , //virtual jlong JNICALL GetLongField(jobject obj, jfieldID fieldID);
new pf_float_IntPtr_IntPtr ( JNIEnv . GetFloatField ) , //virtual jfloat JNICALL GetFloatField(jobject obj, jfieldID fieldID);
new pf_double_IntPtr_IntPtr ( JNIEnv . GetDoubleField ) , //virtual jdouble JNICALL GetDoubleField(jobject obj, jfieldID fieldID);
new pf_void_IntPtr_IntPtr_IntPtr ( JNIEnv . SetObjectField ) , //virtual void JNICALL SetObjectField(jobject obj, jfieldID fieldID, jobject val);
new pf_void_IntPtr_IntPtr_sbyte ( JNIEnv . SetBooleanField ) , //virtual void JNICALL SetBooleanField(jobject obj, jfieldID fieldID, jboolean val);
new pf_void_IntPtr_IntPtr_sbyte ( JNIEnv . SetByteField ) , //virtual void JNICALL SetByteField(jobject obj, jfieldID fieldID, jbyte val);
2004-09-05 13:37:58 +04:00
new pf_void_IntPtr_IntPtr_ushort ( JNIEnv . SetCharField ) , //virtual void JNICALL SetCharField(jobject obj, jfieldID fieldID, jchar val);
2004-08-30 19:56:23 +04:00
new pf_void_IntPtr_IntPtr_short ( JNIEnv . SetShortField ) , //virtual void JNICALL SetShortField(jobject obj, jfieldID fieldID, jshort val);
new pf_void_IntPtr_IntPtr_int ( JNIEnv . SetIntField ) , //virtual void JNICALL SetIntField(jobject obj, jfieldID fieldID, jint val);
new pf_void_IntPtr_IntPtr_long ( JNIEnv . SetLongField ) , //virtual void JNICALL SetLongField(jobject obj, jfieldID fieldID, jlong val);
new pf_void_IntPtr_IntPtr_float ( JNIEnv . SetFloatField ) , //virtual void JNICALL SetFloatField(jobject obj, jfieldID fieldID, jfloat val);
new pf_void_IntPtr_IntPtr_double ( JNIEnv . SetDoubleField ) , //virtual void JNICALL SetDoubleField(jobject obj, jfieldID fieldID, jdouble val);
new pf_IntPtr_IntPtr_pbyte_pbyte ( JNIEnv . GetStaticMethodID ) , //virtual jmethodID JNICALL GetStaticMethodID(jclass clazz, const char *name, const char *sig);
null , //virtual jobject JNICALL CallStaticObjectMethod(jclass clazz, jmethodID methodID, ...);
null , //virtual jobject JNICALL CallStaticObjectMethodV(jclass clazz, jmethodID methodID, va_list args);
new pf_IntPtr_IntPtr_IntPtr_pjvalue ( JNIEnv . CallStaticObjectMethodA ) , //virtual jobject JNICALL CallStaticObjectMethodA(jclass clazz, jmethodID methodID, jvalue *args);
null , //virtual jboolean JNICALL CallStaticBooleanMethod(jclass clazz, jmethodID methodID, ...);
null , //virtual jboolean JNICALL CallStaticBooleanMethodV(jclass clazz, jmethodID methodID, va_list args);
new pf_sbyte_IntPtr_IntPtr_pjvalue ( JNIEnv . CallStaticBooleanMethodA ) , //virtual jboolean JNICALL CallStaticBooleanMethodA(jclass clazz, jmethodID methodID, jvalue *args);
null , //virtual jbyte JNICALL CallStaticByteMethod(jclass clazz, jmethodID methodID, ...);
null , //virtual jbyte JNICALL CallStaticByteMethodV(jclass clazz, jmethodID methodID, va_list args);
new pf_sbyte_IntPtr_IntPtr_pjvalue ( JNIEnv . CallStaticByteMethodA ) , //virtual jbyte JNICALL CallStaticByteMethodA(jclass clazz, jmethodID methodID, jvalue *args);
null , //virtual jchar JNICALL CallStaticCharMethod(jclass clazz, jmethodID methodID, ...);
null , //virtual jchar JNICALL CallStaticCharMethodV(jclass clazz, jmethodID methodID, va_list args);
2004-09-05 13:37:58 +04:00
new pf_ushort_IntPtr_IntPtr_pjvalue ( JNIEnv . CallStaticCharMethodA ) , //virtual jchar JNICALL CallStaticCharMethodA(jclass clazz, jmethodID methodID, jvalue *args);
2004-08-30 19:56:23 +04:00
null , //virtual jshort JNICALL CallStaticShortMethod(jclass clazz, jmethodID methodID, ...);
null , //virtual jshort JNICALL CallStaticShortMethodV(jclass clazz, jmethodID methodID, va_list args);
new pf_short_IntPtr_IntPtr_pjvalue ( JNIEnv . CallStaticShortMethodA ) , //virtual jshort JNICALL CallStaticShortMethodA(jclass clazz, jmethodID methodID, jvalue *args);
null , //virtual jint JNICALL CallStaticIntMethod(jclass clazz, jmethodID methodID, ...);
null , //virtual jint JNICALL CallStaticIntMethodV(jclass clazz, jmethodID methodID, va_list args);
new pf_int_IntPtr_IntPtr_pjvalue ( JNIEnv . CallStaticIntMethodA ) , //virtual jint JNICALL CallStaticIntMethodA(jclass clazz, jmethodID methodID, jvalue *args);
null , //virtual jlong JNICALL CallStaticLongMethod(jclass clazz, jmethodID methodID, ...);
null , //virtual jlong JNICALL CallStaticLongMethodV(jclass clazz, jmethodID methodID, va_list args);
new pf_long_IntPtr_IntPtr_pjvalue ( JNIEnv . CallStaticLongMethodA ) , //virtual jlong JNICALL CallStaticLongMethodA(jclass clazz, jmethodID methodID, jvalue *args);
null , //virtual jfloat JNICALL CallStaticFloatMethod(jclass clazz, jmethodID methodID, ...);
null , //virtual jfloat JNICALL CallStaticFloatMethodV(jclass clazz, jmethodID methodID, va_list args);
new pf_float_IntPtr_IntPtr_pjvalue ( JNIEnv . CallStaticFloatMethodA ) , //virtual jfloat JNICALL CallStaticFloatMethodA(jclass clazz, jmethodID methodID, jvalue *args);
null , //virtual jdouble JNICALL CallStaticDoubleMethod(jclass clazz, jmethodID methodID, ...);
null , //virtual jdouble JNICALL CallStaticDoubleMethodV(jclass clazz, jmethodID methodID, va_list args);
new pf_double_IntPtr_IntPtr_pjvalue ( JNIEnv . CallStaticDoubleMethodA ) , //virtual jdouble JNICALL CallStaticDoubleMethodA(jclass clazz, jmethodID methodID, jvalue *args);
null , //virtual void JNICALL CallStaticVoidMethod(jclass cls, jmethodID methodID, ...);
null , //virtual void JNICALL CallStaticVoidMethodV(jclass cls, jmethodID methodID, va_list args);
new pf_void_IntPtr_IntPtr_pjvalue ( JNIEnv . CallStaticVoidMethodA ) , //virtual void JNICALL CallStaticVoidMethodA(jclass cls, jmethodID methodID, jvalue * args);
new pf_IntPtr_IntPtr_pbyte_pbyte ( JNIEnv . GetStaticFieldID ) , //virtual jfieldID JNICALL GetStaticFieldID(jclass clazz, const char *name, const char *sig);
new pf_IntPtr_IntPtr_IntPtr ( JNIEnv . GetStaticObjectField ) , //virtual jobject JNICALL GetObjectField(jobject obj, jfieldID fieldID);
new pf_sbyte_IntPtr_IntPtr ( JNIEnv . GetStaticBooleanField ) , //virtual jboolean JNICALL GetBooleanField(jobject obj, jfieldID fieldID);
new pf_sbyte_IntPtr_IntPtr ( JNIEnv . GetStaticByteField ) , //virtual jbyte JNICALL GetByteField(jobject obj, jfieldID fieldID);
2004-09-05 13:37:58 +04:00
new pf_ushort_IntPtr_IntPtr ( JNIEnv . GetStaticCharField ) , //virtual jchar JNICALL GetCharField(jobject obj, jfieldID fieldID);
2004-08-30 19:56:23 +04:00
new pf_short_IntPtr_IntPtr ( JNIEnv . GetStaticShortField ) , //virtual jshort JNICALL GetShortField(jobject obj, jfieldID fieldID);
new pf_int_IntPtr_IntPtr ( JNIEnv . GetStaticIntField ) , //virtual jint JNICALL GetIntField(jobject obj, jfieldID fieldID);
new pf_long_IntPtr_IntPtr ( JNIEnv . GetStaticLongField ) , //virtual jlong JNICALL GetLongField(jobject obj, jfieldID fieldID);
new pf_float_IntPtr_IntPtr ( JNIEnv . GetStaticFloatField ) , //virtual jfloat JNICALL GetFloatField(jobject obj, jfieldID fieldID);
new pf_double_IntPtr_IntPtr ( JNIEnv . GetStaticDoubleField ) , //virtual jdouble JNICALL GetDoubleField(jobject obj, jfieldID fieldID);
new pf_void_IntPtr_IntPtr_IntPtr ( JNIEnv . SetStaticObjectField ) , //virtual void JNICALL SetObjectField(jobject obj, jfieldID fieldID, jobject val);
new pf_void_IntPtr_IntPtr_sbyte ( JNIEnv . SetStaticBooleanField ) , //virtual void JNICALL SetBooleanField(jobject obj, jfieldID fieldID, jboolean val);
new pf_void_IntPtr_IntPtr_sbyte ( JNIEnv . SetStaticByteField ) , //virtual void JNICALL SetByteField(jobject obj, jfieldID fieldID, jbyte val);
2004-09-05 13:37:58 +04:00
new pf_void_IntPtr_IntPtr_ushort ( JNIEnv . SetStaticCharField ) , //virtual void JNICALL SetCharField(jobject obj, jfieldID fieldID, jchar val);
2004-08-30 19:56:23 +04:00
new pf_void_IntPtr_IntPtr_short ( JNIEnv . SetStaticShortField ) , //virtual void JNICALL SetShortField(jobject obj, jfieldID fieldID, jshort val);
new pf_void_IntPtr_IntPtr_int ( JNIEnv . SetStaticIntField ) , //virtual void JNICALL SetIntField(jobject obj, jfieldID fieldID, jint val);
new pf_void_IntPtr_IntPtr_long ( JNIEnv . SetStaticLongField ) , //virtual void JNICALL SetLongField(jobject obj, jfieldID fieldID, jlong val);
new pf_void_IntPtr_IntPtr_float ( JNIEnv . SetStaticFloatField ) , //virtual void JNICALL SetFloatField(jobject obj, jfieldID fieldID, jfloat val);
new pf_void_IntPtr_IntPtr_double ( JNIEnv . SetStaticDoubleField ) , //virtual void JNICALL SetDoubleField(jobject obj, jfieldID fieldID, jdouble val);
2004-09-05 13:37:58 +04:00
new pf_IntPtr_pjchar_int ( JNIEnv . NewString ) , //virtual jstring JNICALL NewString(const jchar *unicode, jsize len);
2004-08-30 19:56:23 +04:00
new pf_int_IntPtr ( JNIEnv . GetStringLength ) , //virtual jsize JNICALL GetStringLength(jstring str);
2004-09-05 13:37:58 +04:00
new pf_pjchar_IntPtr_pjboolean ( JNIEnv . GetStringChars ) , //virtual const jchar *JNICALL GetStringChars(jstring str, jboolean *isCopy);
new pf_void_IntPtr_pjchar ( JNIEnv . ReleaseStringChars ) , //virtual void JNICALL ReleaseStringChars(jstring str, const jchar *chars);
2004-08-30 19:56:23 +04:00
2004-09-05 13:37:58 +04:00
new pf_IntPtr_pbyte ( JNIEnv . NewStringUTF ) , //virtual jstring JNICALL NewStringUTF(const char *utf);
2004-08-30 19:56:23 +04:00
new pf_int_IntPtr ( JNIEnv . GetStringUTFLength ) , //virtual jsize JNICALL GetStringUTFLength(jstring str);
2004-09-05 13:37:58 +04:00
new pf_pbyte_IntPtr_pjboolean ( JNIEnv . GetStringUTFChars ) , //virtual const char* JNICALL GetStringUTFChars(jstring str, jboolean *isCopy);
new pf_void_IntPtr_pbyte ( JNIEnv . ReleaseStringUTFChars ) , //virtual void JNICALL ReleaseStringUTFChars(jstring str, const char* chars);
2004-08-30 19:56:23 +04:00
new pf_int_IntPtr ( JNIEnv . GetArrayLength ) , //virtual jsize JNICALL GetArrayLength(jarray array);
new pf_IntPtr_int_IntPtr_IntPtr ( JNIEnv . NewObjectArray ) , //virtual jobjectArray JNICALL NewObjectArray(jsize len, jclass clazz, jobject init);
new pf_IntPtr_IntPtr_int ( JNIEnv . GetObjectArrayElement ) , //virtual jobject JNICALL GetObjectArrayElement(jobjectArray array, jsize index);
new pf_void_IntPtr_int_IntPtr ( JNIEnv . SetObjectArrayElement ) , //virtual void JNICALL SetObjectArrayElement(jobjectArray array, jsize index, jobject val);
new pf_IntPtr_int ( JNIEnv . NewBooleanArray ) , //virtual jbooleanArray JNICALL NewBooleanArray(jsize len);
new pf_IntPtr_int ( JNIEnv . NewByteArray ) , //virtual jbyteArray JNICALL NewByteArray(jsize len);
new pf_IntPtr_int ( JNIEnv . NewCharArray ) , //virtual jcharArray JNICALL NewCharArray(jsize len);
new pf_IntPtr_int ( JNIEnv . NewShortArray ) , //virtual jshortArray JNICALL NewShortArray(jsize len);
new pf_IntPtr_int ( JNIEnv . NewIntArray ) , //virtual jintArray JNICALL NewIntArray(jsize len);
new pf_IntPtr_int ( JNIEnv . NewLongArray ) , //virtual jlongArray JNICALL NewLongArray(jsize len);
new pf_IntPtr_int ( JNIEnv . NewFloatArray ) , //virtual jfloatArray JNICALL NewFloatArray(jsize len);
new pf_IntPtr_int ( JNIEnv . NewDoubleArray ) , //virtual jdoubleArray JNICALL NewDoubleArray(jsize len);
2004-09-05 13:37:58 +04:00
new pf_pjboolean_IntPtr_pjboolean ( JNIEnv . GetBooleanArrayElements ) , //virtual jboolean * JNICALL GetBooleanArrayElements(jbooleanArray array, jboolean *isCopy);
new pf_pjbyte_IntPtr_pjboolean ( JNIEnv . GetByteArrayElements ) , //virtual jbyte * JNICALL GetByteArrayElements(jbyteArray array, jboolean *isCopy);
new pf_pjchar_IntPtr_pjboolean ( JNIEnv . GetCharArrayElements ) , //virtual jchar * JNICALL GetCharArrayElements(jcharArray array, jboolean *isCopy);
new pf_pjshort_IntPtr_pjboolean ( JNIEnv . GetShortArrayElements ) , //virtual jshort * JNICALL GetShortArrayElements(jshortArray array, jboolean *isCopy);
new pf_pjint_IntPtr_pjboolean ( JNIEnv . GetIntArrayElements ) , //virtual jint * JNICALL GetIntArrayElements(jintArray array, jboolean *isCopy);
new pf_pjlong_IntPtr_pjboolean ( JNIEnv . GetLongArrayElements ) , //virtual jlong * JNICALL GetLongArrayElements(jlongArray array, jboolean *isCopy);
new pf_pjfloat_IntPtr_pjboolean ( JNIEnv . GetFloatArrayElements ) , //virtual jfloat * JNICALL GetFloatArrayElements(jfloatArray array, jboolean *isCopy);
new pf_pjdouble_IntPtr_pjboolean ( JNIEnv . GetDoubleArrayElements ) , //virtual jdouble * JNICALL GetDoubleArrayElements(jdoubleArray array, jboolean *isCopy);
new pf_void_IntPtr_pjboolean_int ( JNIEnv . ReleaseBooleanArrayElements ) , //virtual void JNICALL ReleaseBooleanArrayElements(jbooleanArray array, jboolean *elems, jint mode);
new pf_void_IntPtr_pjbyte_int ( JNIEnv . ReleaseByteArrayElements ) , //virtual void JNICALL ReleaseByteArrayElements(jbyteArray array, jbyte *elems, jint mode);
new pf_void_IntPtr_pjchar_int ( JNIEnv . ReleaseCharArrayElements ) , //virtual void JNICALL ReleaseCharArrayElements(jcharArray array, jchar *elems, jint mode);
new pf_void_IntPtr_pjshort_int ( JNIEnv . ReleaseShortArrayElements ) , //virtual void JNICALL ReleaseShortArrayElements(jshortArray array, jshort *elems, jint mode);
new pf_void_IntPtr_pjint_int ( JNIEnv . ReleaseIntArrayElements ) , //virtual void JNICALL ReleaseIntArrayElements(jintArray array, jint *elems, jint mode);
new pf_void_IntPtr_pjlong_int ( JNIEnv . ReleaseLongArrayElements ) , //virtual void JNICALL ReleaseLongArrayElements(jlongArray array, jlong *elems, jint mode);
new pf_void_IntPtr_pjfloat_int ( JNIEnv . ReleaseFloatArrayElements ) , //virtual void JNICALL ReleaseFloatArrayElements(jfloatArray array, jfloat *elems, jint mode);
new pf_void_IntPtr_pjdouble_int ( JNIEnv . ReleaseDoubleArrayElements ) , //virtual void JNICALL ReleaseDoubleArrayElements(jdoubleArray array, jdouble *elems, jint mode);
2004-08-30 19:56:23 +04:00
new pf_void_IntPtr_int_int_IntPtr ( JNIEnv . GetBooleanArrayRegion ) , //virtual void JNICALL GetBooleanArrayRegion(jbooleanArray array, jsize start, jsize l, jboolean *buf);
new pf_void_IntPtr_int_int_IntPtr ( JNIEnv . GetByteArrayRegion ) , //virtual void JNICALL GetByteArrayRegion(jbyteArray array, jsize start, jsize len, jbyte *buf);
new pf_void_IntPtr_int_int_IntPtr ( JNIEnv . GetCharArrayRegion ) , //virtual void JNICALL GetCharArrayRegion(jcharArray array, jsize start, jsize len, jchar *buf);
new pf_void_IntPtr_int_int_IntPtr ( JNIEnv . GetShortArrayRegion ) , //virtual void JNICALL GetShortArrayRegion(jshortArray array, jsize start, jsize len, jshort *buf);
new pf_void_IntPtr_int_int_IntPtr ( JNIEnv . GetIntArrayRegion ) , //virtual void JNICALL GetIntArrayRegion(jintArray array, jsize start, jsize len, jint *buf);
new pf_void_IntPtr_int_int_IntPtr ( JNIEnv . GetLongArrayRegion ) , //virtual void JNICALL GetLongArrayRegion(jlongArray array, jsize start, jsize len, jlong *buf);
new pf_void_IntPtr_int_int_IntPtr ( JNIEnv . GetFloatArrayRegion ) , //virtual void JNICALL GetFloatArrayRegion(jfloatArray array, jsize start, jsize len, jfloat *buf);
new pf_void_IntPtr_int_int_IntPtr ( JNIEnv . GetDoubleArrayRegion ) , //virtual void JNICALL GetDoubleArrayRegion(jdoubleArray array, jsize start, jsize len, jdouble *buf);
new pf_void_IntPtr_int_int_IntPtr ( JNIEnv . SetBooleanArrayRegion ) , //virtual void JNICALL SetBooleanArrayRegion(jbooleanArray array, jsize start, jsize l, jboolean *buf);
new pf_void_IntPtr_int_int_IntPtr ( JNIEnv . SetByteArrayRegion ) , //virtual void JNICALL SetByteArrayRegion(jbyteArray array, jsize start, jsize len, jbyte *buf);
new pf_void_IntPtr_int_int_IntPtr ( JNIEnv . SetCharArrayRegion ) , //virtual void JNICALL SetCharArrayRegion(jcharArray array, jsize start, jsize len, jchar *buf);
new pf_void_IntPtr_int_int_IntPtr ( JNIEnv . SetShortArrayRegion ) , //virtual void JNICALL SetShortArrayRegion(jshortArray array, jsize start, jsize len, jshort *buf);
new pf_void_IntPtr_int_int_IntPtr ( JNIEnv . SetIntArrayRegion ) , //virtual void JNICALL SetIntArrayRegion(jintArray array, jsize start, jsize len, jint *buf);
new pf_void_IntPtr_int_int_IntPtr ( JNIEnv . SetLongArrayRegion ) , //virtual void JNICALL SetLongArrayRegion(jlongArray array, jsize start, jsize len, jlong *buf);
new pf_void_IntPtr_int_int_IntPtr ( JNIEnv . SetFloatArrayRegion ) , //virtual void JNICALL SetFloatArrayRegion(jfloatArray array, jsize start, jsize len, jfloat *buf);
new pf_void_IntPtr_int_int_IntPtr ( JNIEnv . SetDoubleArrayRegion ) , //virtual void JNICALL SetDoubleArrayRegion(jdoubleArray array, jsize start, jsize len, jdouble *buf);
new pf_int_IntPtr_pJNINativeMethod_int ( JNIEnv . RegisterNatives ) , //virtual jint JNICALL RegisterNatives(jclass clazz, const JNINativeMethod *methods, jint nMethods);
new pf_int_IntPtr ( JNIEnv . UnregisterNatives ) , //virtual jint JNICALL UnregisterNatives(jclass clazz);
new pf_int_IntPtr ( JNIEnv . MonitorEnter ) , //virtual jint JNICALL MonitorEnter(jobject obj);
new pf_int_IntPtr ( JNIEnv . MonitorExit ) , //virtual jint JNICALL MonitorExit(jobject obj);
new pf_int_ppJavaVM ( JNIEnv . GetJavaVM ) , //virtual jint JNICALL GetJavaVM(JavaVM **vm);
new pf_void_IntPtr_int_int_IntPtr ( JNIEnv . GetStringRegion ) , //virtual void JNICALL GetStringRegion(jstring str, jsize start, jsize len, jchar *buf);
new pf_void_IntPtr_int_int_IntPtr ( JNIEnv . GetStringUTFRegion ) , //virtual void JNICALL GetStringUTFRegion(jstring str, jsize start, jsize len, char *buf);
2005-09-01 11:34:53 +04:00
new pf_pvoid_IntPtr_pjboolean ( JNIEnv . GetPrimitiveArrayCritical ) , //virtual void* JNICALL GetPrimitiveArrayCritical(jarray array, jboolean *isCopy);
new pf_void_IntPtr_pvoid_int ( JNIEnv . ReleasePrimitiveArrayCritical ) , //virtual void JNICALL ReleasePrimitiveArrayCritical(jarray array, void *carray, jint mode);
2004-08-30 19:56:23 +04:00
2005-09-01 11:34:53 +04:00
new pf_pjchar_IntPtr_pjboolean ( JNIEnv . GetStringCritical ) , //virtual const jchar* JNICALL GetStringCritical(jstring string, jboolean *isCopy);
new pf_void_IntPtr_pjchar ( JNIEnv . ReleaseStringCritical ) , //virtual void JNICALL ReleaseStringCritical(jstring string, const jchar *cstring);
2004-08-30 19:56:23 +04:00
2004-09-05 13:37:58 +04:00
new pf_IntPtr_IntPtr ( JNIEnv . NewWeakGlobalRef ) , //virtual jweak JNICALL NewWeakGlobalRef(jobject obj);
new pf_void_IntPtr ( JNIEnv . DeleteWeakGlobalRef ) , //virtual void JNICALL DeleteWeakGlobalRef(jweak ref);
2004-08-30 19:56:23 +04:00
new pf_sbyte ( JNIEnv . ExceptionCheck ) , //virtual jboolean JNICALL ExceptionCheck();
2004-11-23 20:46:39 +03:00
new pf_IntPtr_IntPtr_long ( JNIEnv . NewDirectByteBuffer ) , //virtual jobject JNICALL NewDirectByteBuffer(void* address, jlong capacity);
new pf_IntPtr_IntPtr ( JNIEnv . GetDirectBufferAddress ) , //virtual void* JNICALL GetDirectBufferAddress(jobject buf);
2007-09-07 09:19:11 +04:00
new pf_long_IntPtr ( JNIEnv . GetDirectBufferCapacity ) , //virtual jlong JNICALL GetDirectBufferCapacity(jobject buf);
new pf_int_IntPtr ( JNIEnv . GetObjectRefType ) // virtual jobjectRefType GetObjectRefType(jobject obj);
2004-08-30 19:56:23 +04:00
} ;
2004-09-09 15:17:55 +04:00
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
[StructLayout(LayoutKind.Sequential)]
unsafe struct JavaVMAttachArgs
{
internal jint version ;
2007-04-02 12:25:30 +04:00
internal byte * name ;
2004-09-09 15:17:55 +04:00
internal jobject group ;
}
[StructLayout(LayoutKind.Sequential)]
unsafe struct JavaVM
{
internal static JavaVM * pJavaVM ;
void * * vtable ;
void * firstVtableEntry ;
delegate int pf_int ( JavaVM * pJVM ) ;
delegate int pf_int_ppvoid_pvoid ( JavaVM * pJVM , void * * p1 , void * p2 ) ;
delegate int pf_int_ppvoid_int ( JavaVM * pJVM , void * * p1 , int p2 ) ;
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
static Delegate [ ] vtableDelegates =
2004-08-30 19:56:23 +04:00
{
null ,
null ,
null ,
new pf_int ( DestroyJavaVM ) ,
new pf_int_ppvoid_pvoid ( AttachCurrentThread ) ,
new pf_int ( DetachCurrentThread ) ,
new pf_int_ppvoid_int ( GetEnv ) ,
new pf_int_ppvoid_pvoid ( AttachCurrentThreadAsDaemon )
} ;
2004-09-09 15:17:55 +04:00
static JavaVM ( )
{
JNI . jvmCreated = true ;
pJavaVM = ( JavaVM * ) ( void * ) JniMem . Alloc ( IntPtr . Size * ( 1 + vtableDelegates . Length ) ) ;
pJavaVM - > vtable = & pJavaVM - > firstVtableEntry ;
for ( int i = 0 ; i < vtableDelegates . Length ; i + + )
{
pJavaVM - > vtable [ i ] = JniHelper . ikvm_MarshalDelegate ( vtableDelegates [ i ] ) ;
}
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static jint DestroyJavaVM ( JavaVM * pJVM )
2004-08-30 19:56:23 +04:00
{
2005-02-02 18:11:26 +03:00
if ( JNI . jvmDestroyed )
{
return JNIEnv . JNI_ERR ;
}
JNI . jvmDestroyed = true ;
2007-06-05 10:57:18 +04:00
IKVM . NativeCode . java . lang . Thread . WaitUntilLastJniThread ( ) ;
2005-02-02 18:11:26 +03:00
return JNIEnv . JNI_OK ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static jint AttachCurrentThread ( JavaVM * pJVM , void * * penv , void * args )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
return AttachCurrentThreadImpl ( pJVM , penv , ( JavaVMAttachArgs * ) args , false ) ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static jint AttachCurrentThreadImpl ( JavaVM * pJVM , void * * penv , JavaVMAttachArgs * pAttachArgs , bool asDaemon )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
if ( pAttachArgs ! = null )
2004-08-30 19:56:23 +04:00
{
2005-02-02 18:11:26 +03:00
if ( ! JNI . IsSupportedJniVersion ( pAttachArgs - > version ) | | pAttachArgs - > version = = JNIEnv . JNI_VERSION_1_1 )
2004-09-09 15:17:55 +04:00
{
* penv = null ;
return JNIEnv . JNI_EVERSION ;
}
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
JNIEnv * p = TlsHack . pJNIEnv ;
if ( p ! = null )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
* penv = p ;
return JNIEnv . JNI_OK ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
// NOTE if we're here, it is *very* likely that the thread was created by native code and not by managed code,
// but it's not impossible that the thread started life as a managed thread and if it did the changes to the
// thread we're making are somewhat dubious.
2005-02-02 18:11:26 +03:00
System . Threading . Thread . CurrentThread . IsBackground = asDaemon ;
2004-09-09 15:17:55 +04:00
if ( pAttachArgs ! = null )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
if ( pAttachArgs - > name ! = null & & System . Threading . Thread . CurrentThread . Name = = null )
{
2005-02-02 18:11:26 +03:00
try
{
2007-04-02 12:25:30 +04:00
System . Threading . Thread . CurrentThread . Name = JNIEnv . StringFromUTF8 ( pAttachArgs - > name ) ;
2005-02-02 18:11:26 +03:00
}
catch ( InvalidOperationException )
{
// someone beat us to it...
}
2004-09-09 15:17:55 +04:00
}
// NOTE we're calling UnwrapRef on a null reference, but that's OK because group is a global reference
object threadGroup = p - > UnwrapRef ( pAttachArgs - > group ) ;
if ( threadGroup ! = null )
{
2007-06-05 10:57:18 +04:00
IKVM . NativeCode . java . lang . Thread . AttachThreadFromJni ( threadGroup ) ;
2004-09-09 15:17:55 +04:00
}
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
* penv = JNIEnv . CreateJNIEnv ( ) ;
return JNIEnv . JNI_OK ;
2003-01-07 14:40:11 +03:00
}
2003-01-17 17:34:33 +03:00
2004-09-09 15:17:55 +04:00
internal static jint DetachCurrentThread ( JavaVM * pJVM )
2003-01-07 14:40:11 +03:00
{
2004-09-09 15:17:55 +04:00
if ( TlsHack . pJNIEnv = = null )
2003-01-07 14:40:11 +03:00
{
2005-02-02 18:11:26 +03:00
// the JDK allows detaching from an already detached thread
return JNIEnv . JNI_OK ;
2003-01-07 14:40:11 +03:00
}
2004-09-09 15:17:55 +04:00
// TODO if we set Thread.IsBackground to false when we attached, now might be a good time to set it back to true.
JNIEnv . FreeJNIEnv ( ) ;
2008-04-25 08:48:57 +04:00
IKVM . NativeCode . java . lang . VMThread . jniDetach ( ) ;
2004-09-09 15:17:55 +04:00
return JNIEnv . JNI_OK ;
2003-01-07 14:40:11 +03:00
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static jint GetEnv ( JavaVM * pJVM , void * * penv , jint version )
2004-08-30 19:56:23 +04:00
{
2005-02-02 18:11:26 +03:00
if ( JNI . IsSupportedJniVersion ( version ) )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
JNIEnv * p = TlsHack . pJNIEnv ;
if ( p ! = null )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
* penv = p ;
return JNIEnv . JNI_OK ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
* penv = null ;
return JNIEnv . JNI_EDETACHED ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
* penv = null ;
return JNIEnv . JNI_EVERSION ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static jint AttachCurrentThreadAsDaemon ( JavaVM * pJVM , void * * penv , void * args )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
return AttachCurrentThreadImpl ( pJVM , penv , ( JavaVMAttachArgs * ) args , true ) ;
2004-08-30 19:56:23 +04:00
}
}
2004-09-09 15:17:55 +04:00
[StructLayout(LayoutKind.Sequential)]
unsafe struct JNIEnv
{
2005-02-02 18:11:26 +03:00
// NOTE LOCAL_REF_BUCKET_SIZE must be at least 512 to allow all method arguments to fit
// in a single slot, because Frame.MakeLocalRef() doesn't support spilling into a new bucket
2004-09-09 15:17:55 +04:00
internal const int LOCAL_REF_SHIFT = 10 ;
internal const int LOCAL_REF_BUCKET_SIZE = ( 1 < < LOCAL_REF_SHIFT ) ;
internal const int LOCAL_REF_MASK = ( LOCAL_REF_BUCKET_SIZE - 1 ) ;
internal const int JNI_OK = 0 ;
internal const int JNI_ERR = - 1 ;
internal const int JNI_EDETACHED = - 2 ;
internal const int JNI_EVERSION = - 3 ;
internal const int JNI_COMMIT = 1 ;
internal const int JNI_ABORT = 2 ;
internal const int JNI_VERSION_1_1 = 0x00010001 ;
internal const int JNI_VERSION_1_2 = 0x00010002 ;
internal const int JNI_VERSION_1_4 = 0x00010004 ;
2007-09-07 09:19:11 +04:00
internal const int JNI_VERSION_1_6 = 0x00010006 ;
internal const int JNIInvalidRefType = 0 ;
internal const int JNILocalRefType = 1 ;
internal const int JNIGlobalRefType = 2 ;
internal const int JNIWeakGlobalRefType = 3 ;
2004-09-09 15:17:55 +04:00
internal const sbyte JNI_TRUE = 1 ;
internal const sbyte JNI_FALSE = 0 ;
2009-05-25 08:01:35 +04:00
private void * vtable ;
private GCHandle managedJNIEnv ;
private GCHandle criticalArrayHandle1 ;
private GCHandle criticalArrayHandle2 ;
2004-09-09 15:17:55 +04:00
private static LocalDataStoreSlot cleanupHelperDataSlot = System . Threading . Thread . AllocateDataSlot ( ) ;
2007-12-27 18:16:49 +03:00
static JNIEnv ( )
{
// we set the field here so that IKVM.Runtime.dll doesn't have to load us if we're not otherwise needed
IKVM . NativeCode . java . lang . SecurityManager . jniAssembly = typeof ( JNIEnv ) . Assembly ;
}
2009-05-25 08:01:35 +04:00
internal ManagedJNIEnv GetManagedJNIEnv ( )
{
return ( ManagedJNIEnv ) managedJNIEnv . Target ;
}
internal sealed class ManagedJNIEnv
{
internal ClassLoaderWrapper classLoader ;
internal RuntimeMethodHandle currentMethod ;
internal object [ ] [ ] localRefs ;
internal int localRefSlot ;
internal Exception pendingException ;
internal ManagedJNIEnv ( )
{
localRefs = new object [ 32 ] [ ] ;
localRefs [ 0 ] = new object [ JNIEnv . LOCAL_REF_BUCKET_SIZE ] ;
// stuff something in the first entry to make sure we don't hand out a zero handle
// (a zero handle corresponds to a null reference)
localRefs [ 0 ] [ 0 ] = "" ;
}
}
2004-09-09 15:17:55 +04:00
unsafe class JNIEnvCleanupHelper
{
private JNIEnv * pJNIEnv ;
internal JNIEnvCleanupHelper ( JNIEnv * pJNIEnv )
{
this . pJNIEnv = pJNIEnv ;
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
~ JNIEnvCleanupHelper ( )
{
2005-05-02 11:53:42 +04:00
// NOTE don't clean up when we're being unloaded (we'll get cleaned up anyway and because
// of the unorderedness of the finalization process native code could still be run after
// we run).
// NOTE when we're not the default AppDomain and we're being unloaded,
// we're leaking the JNIEnv (but since JNI outside of the default AppDomain isn't currently supported,
// I can live with that).
2005-05-02 12:12:36 +04:00
if ( ! Environment . HasShutdownStarted )
2005-05-02 11:53:42 +04:00
{
2009-05-25 08:01:35 +04:00
if ( pJNIEnv - > managedJNIEnv . IsAllocated )
2005-05-02 11:53:42 +04:00
{
2009-05-25 08:01:35 +04:00
pJNIEnv - > managedJNIEnv . Free ( ) ;
2005-05-02 11:53:42 +04:00
}
2005-09-01 11:34:53 +04:00
if ( pJNIEnv - > criticalArrayHandle1 . IsAllocated )
{
pJNIEnv - > criticalArrayHandle1 . Free ( ) ;
}
if ( pJNIEnv - > criticalArrayHandle2 . IsAllocated )
{
pJNIEnv - > criticalArrayHandle2 . Free ( ) ;
}
2005-05-02 11:53:42 +04:00
JniMem . Free ( ( IntPtr ) ( void * ) pJNIEnv ) ;
}
2004-09-09 15:17:55 +04:00
}
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static JNIEnv * CreateJNIEnv ( )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
JNIEnv * pJNIEnv = TlsHack . pJNIEnv = ( JNIEnv * ) JniMem . Alloc ( sizeof ( JNIEnv ) ) ;
2005-05-02 12:12:36 +04:00
// don't touch the LocalDataStore slot when we're being unloaded
// (it may have been finalized already)
if ( ! Environment . HasShutdownStarted )
{
System . Threading . Thread . SetData ( cleanupHelperDataSlot , new JNIEnvCleanupHelper ( pJNIEnv ) ) ;
}
2004-09-09 15:17:55 +04:00
pJNIEnv - > vtable = VtableBuilder . vtable ;
2009-05-25 08:01:35 +04:00
pJNIEnv - > managedJNIEnv = GCHandle . Alloc ( new ManagedJNIEnv ( ) ) ;
2005-09-01 11:34:53 +04:00
pJNIEnv - > criticalArrayHandle1 = GCHandle . Alloc ( null , GCHandleType . Pinned ) ;
pJNIEnv - > criticalArrayHandle2 = GCHandle . Alloc ( null , GCHandleType . Pinned ) ;
2004-09-09 15:17:55 +04:00
return pJNIEnv ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static void FreeJNIEnv ( )
2004-08-30 19:56:23 +04:00
{
2005-05-02 11:53:42 +04:00
// don't touch the LocalDataStore slot when we're being unloaded
// (it may have been finalized already)
2005-05-02 12:12:36 +04:00
if ( ! Environment . HasShutdownStarted )
2005-05-02 11:53:42 +04:00
{
// the cleanup helper will eventually free the JNIEnv
System . Threading . Thread . SetData ( cleanupHelperDataSlot , null ) ;
}
2004-09-09 15:17:55 +04:00
TlsHack . pJNIEnv = null ;
2004-08-30 19:56:23 +04:00
}
2007-04-02 12:25:30 +04:00
internal static string StringFromOEM ( byte * psz )
2007-01-16 15:10:53 +03:00
{
for ( int i = 0 ; ; i + + )
{
if ( psz [ i ] = = 0 )
{
int oem = System . Globalization . CultureInfo . CurrentCulture . TextInfo . OEMCodePage ;
return new String ( ( sbyte * ) psz , 0 , i , Encoding . GetEncoding ( oem ) ) ;
}
}
}
2004-09-09 15:17:55 +04:00
internal static string StringFromUTF8 ( byte * psz )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
// Sun's modified UTF8 encoding is not compatible with System.Text.Encoding.UTF8,
// so we need to roll our own
int len = 0 ;
bool hasNonAscii = false ;
while ( psz [ len ] ! = 0 )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
hasNonAscii | = psz [ len ] > = 128 ;
len + + ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
if ( ! hasNonAscii )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
// optimize the common case of 7-bit ASCII
return new String ( ( sbyte * ) psz ) ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
StringBuilder sb = new StringBuilder ( len ) ;
for ( int i = 0 ; i < len ; i + + )
{
int c = * psz + + ;
int char2 , char3 ;
switch ( c > > 4 )
{
case 12 :
case 13 :
char2 = * psz + + ;
i + + ;
c = ( ( ( c & 0x1F ) < < 6 ) | ( char2 & 0x3F ) ) ;
break ;
case 14 :
char2 = * psz + + ;
char3 = * psz + + ;
i + + ;
i + + ;
c = ( ( c & 0x0F ) < < 12 ) | ( ( char2 & 0x3F ) < < 6 ) | ( char3 & 0x3F ) ;
break ;
}
sb . Append ( ( char ) c ) ;
}
return sb . ToString ( ) ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
private static int StringUTF8Length ( string s )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
int len = 0 ;
for ( int i = 0 ; i < s . Length ; i + + )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
char ch = s [ i ] ;
if ( ( ch ! = 0 ) & & ( ch < = 0x7F ) )
{
len + + ;
}
else if ( ch < = 0x7FF )
{
len + = 2 ;
}
else
{
len + = 3 ;
}
}
return len ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
// this method returns a simplified method argument descriptor.
// some examples:
// "()V" -> ""
// "(ILjava.lang.String;)I" -> "IL"
// "([Ljava.lang.String;)V" -> "L"
private static string GetMethodArgList ( IntPtr cookie )
2004-09-05 13:37:58 +04:00
{
2004-09-09 15:17:55 +04:00
try
{
StringBuilder sb = new StringBuilder ( ) ;
string s = MethodWrapper . FromCookie ( cookie ) . Signature ;
for ( int i = 1 ; ; i + + )
{
switch ( s [ i ] )
{
case '[' :
while ( s [ i ] = = '[' ) i + + ;
if ( s [ i ] = = 'L' )
{
while ( s [ i ] ! = ';' ) i + + ;
}
sb . Append ( 'L' ) ;
break ;
case 'L' :
while ( s [ i ] ! = ';' ) i + + ;
sb . Append ( 'L' ) ;
break ;
case ')' :
return sb . ToString ( ) ;
default :
sb . Append ( s [ i ] ) ;
break ;
}
}
}
catch
{
Debug . Assert ( false ) ;
throw ;
}
2004-09-05 13:37:58 +04:00
}
2004-09-09 15:17:55 +04:00
internal static jint GetMethodArgs ( JNIEnv * pEnv , IntPtr method , byte * sig )
2004-09-05 13:37:58 +04:00
{
2004-09-09 15:17:55 +04:00
string s = GetMethodArgList ( method ) ;
for ( int i = 0 ; i < s . Length ; i + + )
{
sig [ i ] = ( byte ) s [ i ] ;
}
return s . Length ;
2004-09-05 13:37:58 +04:00
}
2004-09-09 15:17:55 +04:00
internal static jint GetVersion ( JNIEnv * pEnv )
2004-08-30 19:56:23 +04:00
{
2007-09-07 09:19:11 +04:00
return JNI_VERSION_1_6 ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static jclass DefineClass ( JNIEnv * pEnv , byte * name , jobject loader , jbyte * pbuf , jint length )
2004-09-05 13:37:58 +04:00
{
2004-09-09 15:17:55 +04:00
try
2004-09-05 13:37:58 +04:00
{
2004-09-09 15:17:55 +04:00
byte [ ] buf = new byte [ length ] ;
Marshal . Copy ( ( IntPtr ) ( void * ) pbuf , buf , 0 , length ) ;
// TODO what should the protection domain be?
// NOTE I'm assuming name is platform encoded (as opposed to UTF-8), but the Sun JVM only seems to work for ASCII.
2007-05-29 20:27:08 +04:00
return pEnv - > MakeLocalRef ( IKVM . NativeCode . java . lang . ClassLoader . defineClass0 ( pEnv - > UnwrapRef ( loader ) , name ! = null ? StringFromOEM ( name ) : null , buf , 0 , buf . Length , null ) ) ;
2004-09-05 13:37:58 +04:00
}
2004-09-09 15:17:55 +04:00
catch ( Exception x )
2004-09-05 13:37:58 +04:00
{
2004-09-09 15:17:55 +04:00
SetPendingException ( pEnv , x ) ;
return IntPtr . Zero ;
2004-09-05 13:37:58 +04:00
}
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
private static ClassLoaderWrapper FindNativeMethodClassLoader ( JNIEnv * pEnv )
2004-08-30 19:56:23 +04:00
{
2009-05-25 08:01:35 +04:00
ManagedJNIEnv env = pEnv - > GetManagedJNIEnv ( ) ;
if ( env . currentMethod . Value ! = IntPtr . Zero )
2004-09-05 13:37:58 +04:00
{
2009-05-25 08:01:35 +04:00
MethodBase mb = MethodBase . GetMethodFromHandle ( env . currentMethod ) ;
2006-08-14 11:57:03 +04:00
return ClassLoaderWrapper . GetWrapperFromType ( mb . DeclaringType ) . GetClassLoader ( ) ;
2004-09-05 13:37:58 +04:00
}
2009-05-25 08:01:35 +04:00
if ( env . classLoader ! = null )
2005-01-05 15:56:37 +03:00
{
2009-05-25 08:01:35 +04:00
return env . classLoader ;
2005-01-05 15:56:37 +03:00
}
2006-08-14 11:57:03 +04:00
return ClassLoaderWrapper . GetBootstrapClassLoader ( ) ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
2005-02-02 18:11:26 +03:00
internal static jclass FindClass ( JNIEnv * pEnv , byte * pszName )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
try
{
2007-01-16 15:10:53 +03:00
string name = StringFromOEM ( pszName ) ;
2005-02-02 18:11:26 +03:00
// don't allow dotted names!
if ( name . IndexOf ( '.' ) > = 0 )
{
2007-04-23 12:24:33 +04:00
SetPendingException ( pEnv , new java . lang . NoClassDefFoundError ( name ) ) ;
2005-02-02 18:11:26 +03:00
return IntPtr . Zero ;
}
// spec doesn't say it, but Sun allows signature format class names (but not for primitives)
if ( name . StartsWith ( "L" ) & & name . EndsWith ( ";" ) )
{
name = name . Substring ( 1 , name . Length - 2 ) ;
}
2005-08-25 11:46:57 +04:00
TypeWrapper wrapper = FindNativeMethodClassLoader ( pEnv ) . LoadClassByDottedNameFast ( name . Replace ( '/' , '.' ) ) ;
if ( wrapper = = null )
{
2007-04-23 12:24:33 +04:00
SetPendingException ( pEnv , new java . lang . NoClassDefFoundError ( name ) ) ;
2005-08-25 11:46:57 +04:00
return IntPtr . Zero ;
}
2004-09-09 15:17:55 +04:00
wrapper . Finish ( ) ;
// spec doesn't say it, but Sun runs the static initializer
wrapper . RunClassInit ( ) ;
2004-12-21 17:59:29 +03:00
return pEnv - > MakeLocalRef ( wrapper . ClassObject ) ;
}
2004-09-09 15:17:55 +04:00
catch ( Exception x )
{
2005-02-02 18:11:26 +03:00
if ( x is RetargetableJavaException )
{
x = ( ( RetargetableJavaException ) x ) . ToJava ( ) ;
}
2004-09-09 15:17:55 +04:00
SetPendingException ( pEnv , x ) ;
return IntPtr . Zero ;
}
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static jmethodID FromReflectedMethod ( JNIEnv * pEnv , jobject method )
2004-08-30 19:56:23 +04:00
{
2007-05-29 20:27:08 +04:00
return MethodWrapper . FromMethodOrConstructor ( pEnv - > UnwrapRef ( method ) ) . Cookie ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static jfieldID FromReflectedField ( JNIEnv * pEnv , jobject field )
2004-08-30 19:56:23 +04:00
{
2007-05-29 20:27:08 +04:00
return FieldWrapper . FromField ( pEnv - > UnwrapRef ( field ) ) . Cookie ;
2004-08-30 19:56:23 +04:00
}
2004-09-05 13:37:58 +04:00
2005-05-17 17:18:16 +04:00
internal static jobject ToReflectedMethod ( JNIEnv * pEnv , jclass clazz_ignored , jmethodID method , jboolean isStatic )
2004-08-30 19:56:23 +04:00
{
2007-05-29 20:27:08 +04:00
return pEnv - > MakeLocalRef ( MethodWrapper . FromCookie ( method ) . ToMethodOrConstructor ( true ) ) ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static jclass GetSuperclass ( JNIEnv * pEnv , jclass sub )
2004-08-30 19:56:23 +04:00
{
2006-03-27 17:59:59 +04:00
TypeWrapper wrapper = TypeWrapper . FromClass ( pEnv - > UnwrapRef ( sub ) ) . BaseTypeWrapper ;
2004-12-21 17:59:29 +03:00
return pEnv - > MakeLocalRef ( wrapper = = null ? null : wrapper . ClassObject ) ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static jboolean IsAssignableFrom ( JNIEnv * pEnv , jclass sub , jclass super )
{
2006-03-27 17:59:59 +04:00
TypeWrapper w1 = TypeWrapper . FromClass ( pEnv - > UnwrapRef ( sub ) ) ;
TypeWrapper w2 = TypeWrapper . FromClass ( pEnv - > UnwrapRef ( super ) ) ;
2004-09-09 15:17:55 +04:00
return w1 . IsAssignableTo ( w2 ) ? JNI_TRUE : JNI_FALSE ;
2004-08-30 19:56:23 +04:00
}
2005-05-17 17:18:16 +04:00
internal static jobject ToReflectedField ( JNIEnv * pEnv , jclass clazz_ignored , jfieldID field , jboolean isStatic )
2004-09-09 15:17:55 +04:00
{
2007-05-29 20:27:08 +04:00
return pEnv - > MakeLocalRef ( FieldWrapper . FromCookie ( field ) . ToField ( true ) ) ;
2004-09-09 15:17:55 +04:00
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
private static void SetPendingException ( JNIEnv * pEnv , Exception x )
{
2009-05-25 08:01:35 +04:00
pEnv - > GetManagedJNIEnv ( ) . pendingException = ikvm . runtime . Util . mapException ( x ) ;
2004-09-09 15:17:55 +04:00
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static jint Throw ( JNIEnv * pEnv , jthrowable throwable )
{
2009-05-25 08:01:35 +04:00
ManagedJNIEnv env = pEnv - > GetManagedJNIEnv ( ) ;
Exception x = pEnv - > UnwrapRef ( throwable ) as Exception ;
env . pendingException = ( Exception ) x ;
2004-09-09 15:17:55 +04:00
return JNI_OK ;
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static jint ThrowNew ( JNIEnv * pEnv , jclass clazz , byte * msg )
2004-08-30 19:56:23 +04:00
{
2009-05-25 08:01:35 +04:00
ManagedJNIEnv env = pEnv - > GetManagedJNIEnv ( ) ;
2006-03-27 17:59:59 +04:00
TypeWrapper wrapper = TypeWrapper . FromClass ( pEnv - > UnwrapRef ( clazz ) ) ;
2005-01-03 11:26:21 +03:00
MethodWrapper mw = wrapper . GetMethodWrapper ( "<init>" , "(Ljava.lang.String;)V" , false ) ;
2004-08-30 19:56:23 +04:00
if ( mw ! = null )
{
2004-09-09 15:17:55 +04:00
jint rc ;
Exception exception ;
try
{
wrapper . Finish ( ) ;
2008-08-21 10:40:22 +04:00
java . lang . reflect . Constructor cons = ( java . lang . reflect . Constructor ) mw . ToMethodOrConstructor ( false ) ;
2009-05-25 08:01:35 +04:00
exception = ( Exception ) cons . newInstance ( new object [ ] { StringFromOEM ( msg ) } , ( ikvm . @internal . CallerID ) JVM . CreateCallerID ( env . currentMethod ) ) ;
2004-09-09 15:17:55 +04:00
rc = JNI_OK ;
}
2004-12-21 17:59:29 +03:00
catch ( RetargetableJavaException x )
{
exception = x . ToJava ( ) ;
rc = JNI_ERR ;
}
2004-09-09 15:17:55 +04:00
catch ( Exception x )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
exception = x ;
rc = JNI_ERR ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
SetPendingException ( pEnv , exception ) ;
return rc ;
}
else
{
2007-04-23 12:24:33 +04:00
SetPendingException ( pEnv , new java . lang . NoSuchMethodError ( "<init>(Ljava.lang.String;)V" ) ) ;
2004-09-09 15:17:55 +04:00
return JNI_ERR ;
2004-08-30 19:56:23 +04:00
}
}
2004-09-09 15:17:55 +04:00
internal static jthrowable ExceptionOccurred ( JNIEnv * pEnv )
2004-08-30 19:56:23 +04:00
{
2009-05-25 08:01:35 +04:00
ManagedJNIEnv env = pEnv - > GetManagedJNIEnv ( ) ;
return pEnv - > MakeLocalRef ( env . pendingException ) ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static void ExceptionDescribe ( JNIEnv * pEnv )
2004-08-30 19:56:23 +04:00
{
2009-05-25 08:01:35 +04:00
ManagedJNIEnv env = pEnv - > GetManagedJNIEnv ( ) ;
Exception x = env . pendingException ;
2004-09-09 15:17:55 +04:00
if ( x ! = null )
{
SetPendingException ( pEnv , null ) ;
try
{
2007-04-23 12:24:33 +04:00
java . lang . Throwable . instancehelper_printStackTrace ( x ) ;
2004-09-09 15:17:55 +04:00
}
catch ( Exception ex )
{
Debug . Assert ( false , ex . ToString ( ) ) ;
}
}
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static void ExceptionClear ( JNIEnv * pEnv )
2004-08-30 19:56:23 +04:00
{
2009-05-25 08:01:35 +04:00
ManagedJNIEnv env = pEnv - > GetManagedJNIEnv ( ) ;
env . pendingException = null ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static void FatalError ( JNIEnv * pEnv , byte * msg )
2004-08-30 19:56:23 +04:00
{
2007-01-16 15:10:53 +03:00
Console . Error . WriteLine ( "FATAL ERROR in native method: {0}" , msg = = null ? "(null)" : StringFromOEM ( msg ) ) ;
Console . Error . WriteLine ( new StackTrace ( 1 , true ) ) ;
Environment . Exit ( 1 ) ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static jint PushLocalFrame ( JNIEnv * pEnv , jint capacity )
2004-08-30 19:56:23 +04:00
{
2009-05-25 08:01:35 +04:00
ManagedJNIEnv env = pEnv - > GetManagedJNIEnv ( ) ;
object [ ] [ ] localRefs = env . localRefs ;
env . localRefSlot + = 2 ;
if ( env . localRefSlot > = localRefs . Length )
2004-09-09 15:17:55 +04:00
{
object [ ] [ ] tmp = new object [ localRefs . Length * 2 ] [ ] ;
Array . Copy ( localRefs , 0 , tmp , 0 , localRefs . Length ) ;
2009-05-25 08:01:35 +04:00
env . localRefs = localRefs = tmp ;
2004-09-09 15:17:55 +04:00
}
// we use a null slot to mark the fact that we used PushLocalFrame
2009-05-25 08:01:35 +04:00
localRefs [ env . localRefSlot - 1 ] = null ;
if ( localRefs [ env . localRefSlot ] = = null )
2004-09-09 15:17:55 +04:00
{
2005-02-02 18:11:26 +03:00
// we can't use capacity directly, because the array length must be a power of two
// and it can't be bigger than LOCAL_REF_BUCKET_SIZE
int r = 1 ;
capacity = Math . Min ( capacity , LOCAL_REF_BUCKET_SIZE ) ;
while ( r < capacity )
{
r * = 2 ;
}
2009-05-25 08:01:35 +04:00
localRefs [ env . localRefSlot ] = new object [ r ] ;
2004-09-09 15:17:55 +04:00
}
return JNI_OK ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static jobject PopLocalFrame ( JNIEnv * pEnv , jobject result )
2004-08-30 19:56:23 +04:00
{
2009-05-25 08:01:35 +04:00
ManagedJNIEnv env = pEnv - > GetManagedJNIEnv ( ) ;
2004-09-09 15:17:55 +04:00
object res = pEnv - > UnwrapRef ( result ) ;
2009-05-25 08:01:35 +04:00
object [ ] [ ] localRefs = env . localRefs ;
while ( localRefs [ env . localRefSlot ] ! = null )
2004-09-09 15:17:55 +04:00
{
2009-05-25 08:01:35 +04:00
localRefs [ env . localRefSlot ] = null ;
env . localRefSlot - - ;
2004-09-09 15:17:55 +04:00
}
2009-05-25 08:01:35 +04:00
env . localRefSlot - - ;
2004-09-09 15:17:55 +04:00
return pEnv - > MakeLocalRef ( res ) ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static jobject NewGlobalRef ( JNIEnv * pEnv , jobject obj )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
object o = pEnv - > UnwrapRef ( obj ) ;
if ( o = = null )
{
return IntPtr . Zero ;
}
lock ( GlobalRefs . globalRefs )
{
int index = GlobalRefs . globalRefs . IndexOf ( null ) ;
if ( index > = 0 )
{
GlobalRefs . globalRefs [ index ] = o ;
}
else
{
index = GlobalRefs . globalRefs . Add ( o ) ;
}
return ( IntPtr ) ( - ( index + 1 ) ) ;
}
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static void DeleteGlobalRef ( JNIEnv * pEnv , jobject obj )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
int i = obj . ToInt32 ( ) ;
if ( i < 0 )
{
lock ( GlobalRefs . globalRefs )
{
GlobalRefs . globalRefs [ ( - i ) - 1 ] = null ;
}
return ;
}
if ( i > 0 )
{
Debug . Assert ( false , "Local ref passed to DeleteGlobalRef" ) ;
}
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static void DeleteLocalRef ( JNIEnv * pEnv , jobject obj )
2004-08-30 19:56:23 +04:00
{
2009-05-25 08:01:35 +04:00
ManagedJNIEnv env = pEnv - > GetManagedJNIEnv ( ) ;
2004-09-09 15:17:55 +04:00
int i = obj . ToInt32 ( ) ;
if ( i > 0 )
{
2009-05-25 08:01:35 +04:00
object [ ] [ ] localRefs = env . localRefs ;
2004-09-09 15:17:55 +04:00
localRefs [ i > > LOCAL_REF_SHIFT ] [ i & LOCAL_REF_MASK ] = null ;
return ;
}
if ( i < 0 )
{
Debug . Assert ( false , "bogus localref in DeleteLocalRef" ) ;
}
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static jboolean IsSameObject ( JNIEnv * pEnv , jobject obj1 , jobject obj2 )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
return pEnv - > UnwrapRef ( obj1 ) = = pEnv - > UnwrapRef ( obj2 ) ? JNI_TRUE : JNI_FALSE ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static jobject NewLocalRef ( JNIEnv * pEnv , jobject obj )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
return pEnv - > MakeLocalRef ( pEnv - > UnwrapRef ( obj ) ) ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static jint EnsureLocalCapacity ( JNIEnv * pEnv , jint capacity )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
// since we can dynamically grow the local ref table, we'll just return success for any number
return JNI_OK ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static jobject AllocObject ( JNIEnv * pEnv , jclass clazz )
2009-07-30 20:34:30 +04:00
{
return AllocObjectImpl ( pEnv , TypeWrapper . FromClass ( pEnv - > UnwrapRef ( clazz ) ) ) ;
}
private static jobject AllocObjectImpl ( JNIEnv * pEnv , TypeWrapper wrapper )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
try
{
2004-10-19 17:43:55 +04:00
if ( wrapper . IsAbstract )
2004-09-09 15:17:55 +04:00
{
2007-04-23 12:24:33 +04:00
SetPendingException ( pEnv , new java . lang . InstantiationException ( wrapper . Name ) ) ;
2004-09-09 15:17:55 +04:00
return IntPtr . Zero ;
}
wrapper . Finish ( ) ;
return pEnv - > MakeLocalRef ( System . Runtime . Serialization . FormatterServices . GetUninitializedObject ( wrapper . TypeAsBaseType ) ) ;
}
2004-12-21 17:59:29 +03:00
catch ( RetargetableJavaException x )
{
SetPendingException ( pEnv , x . ToJava ( ) ) ;
return IntPtr . Zero ;
}
2004-09-09 15:17:55 +04:00
catch ( Exception x )
{
SetPendingException ( pEnv , x ) ;
return IntPtr . Zero ;
}
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
[StructLayout(LayoutKind.Explicit)]
internal struct jvalue
{
[FieldOffset(0)]
public jboolean z ;
[FieldOffset(0)]
public jbyte b ;
[FieldOffset(0)]
public jchar c ;
[FieldOffset(0)]
public jshort s ;
[FieldOffset(0)]
public jint i ;
[FieldOffset(0)]
public jlong j ;
[FieldOffset(0)]
public jfloat f ;
[FieldOffset(0)]
public jdouble d ;
[FieldOffset(0)]
public jobject l ;
}
private static object InvokeHelper ( JNIEnv * pEnv , jobject obj , jmethodID methodID , jvalue * args , bool nonVirtual )
{
2009-05-25 08:01:35 +04:00
ManagedJNIEnv env = pEnv - > GetManagedJNIEnv ( ) ;
2004-09-09 15:17:55 +04:00
string sig = GetMethodArgList ( methodID ) ;
object [ ] argarray = new object [ sig . Length ] ;
for ( int i = 0 ; i < sig . Length ; i + + )
{
switch ( sig [ i ] )
{
case 'Z' :
2008-08-21 10:40:22 +04:00
argarray [ i ] = java . lang . Boolean . valueOf ( args [ i ] . z ! = JNI_FALSE ) ;
2004-09-09 15:17:55 +04:00
break ;
case 'B' :
2008-08-21 10:40:22 +04:00
argarray [ i ] = java . lang . Byte . valueOf ( ( byte ) args [ i ] . b ) ;
2004-09-09 15:17:55 +04:00
break ;
case 'C' :
2008-08-21 10:40:22 +04:00
argarray [ i ] = java . lang . Character . valueOf ( ( char ) args [ i ] . c ) ;
2004-09-09 15:17:55 +04:00
break ;
case 'S' :
2008-08-21 10:40:22 +04:00
argarray [ i ] = java . lang . Short . valueOf ( args [ i ] . s ) ;
2004-09-09 15:17:55 +04:00
break ;
case 'I' :
2008-08-21 10:40:22 +04:00
argarray [ i ] = java . lang . Integer . valueOf ( args [ i ] . i ) ;
2004-09-09 15:17:55 +04:00
break ;
case 'J' :
2008-08-21 10:40:22 +04:00
argarray [ i ] = java . lang . Long . valueOf ( args [ i ] . j ) ;
2004-09-09 15:17:55 +04:00
break ;
case 'F' :
2008-08-21 10:40:22 +04:00
argarray [ i ] = java . lang . Float . valueOf ( args [ i ] . f ) ;
2004-09-09 15:17:55 +04:00
break ;
case 'D' :
2008-08-21 10:40:22 +04:00
argarray [ i ] = java . lang . Double . valueOf ( args [ i ] . d ) ;
2004-09-09 15:17:55 +04:00
break ;
case 'L' :
argarray [ i ] = pEnv - > UnwrapRef ( args [ i ] . l ) ;
break ;
}
}
try
{
2008-05-31 19:20:29 +04:00
MethodBase caller = null ;
2009-05-25 08:01:35 +04:00
if ( env . currentMethod . Value ! = IntPtr . Zero )
2008-05-31 19:20:29 +04:00
{
2009-05-25 08:01:35 +04:00
caller = MethodBase . GetMethodFromHandle ( env . currentMethod ) ;
2008-05-31 19:20:29 +04:00
}
return MethodWrapper . FromCookie ( methodID ) . InvokeJNI ( pEnv - > UnwrapRef ( obj ) , argarray , nonVirtual , caller ) ;
2004-09-09 15:17:55 +04:00
}
2007-04-23 12:24:33 +04:00
catch ( java . lang . reflect . InvocationTargetException x )
{
2007-12-19 14:28:09 +03:00
SetPendingException ( pEnv , ikvm . runtime . Util . mapException ( x . getCause ( ) ) ) ;
2007-04-23 12:24:33 +04:00
return null ;
}
2004-09-09 15:17:55 +04:00
catch ( Exception x )
{
2007-12-19 14:28:09 +03:00
SetPendingException ( pEnv , ikvm . runtime . Util . mapException ( x ) ) ;
2004-09-09 15:17:55 +04:00
return null ;
}
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static jobject NewObjectA ( JNIEnv * pEnv , jclass clazz , jmethodID methodID , jvalue * args )
2004-08-30 19:56:23 +04:00
{
2009-07-30 20:34:30 +04:00
TypeWrapper wrapper = TypeWrapper . FromClass ( pEnv - > UnwrapRef ( clazz ) ) ;
if ( ! wrapper . IsAbstract & & wrapper . TypeAsBaseType . IsAbstract )
{
// static newinstance helper method
return pEnv - > MakeLocalRef ( InvokeHelper ( pEnv , IntPtr . Zero , methodID , args , false ) ) ;
}
jobject obj = AllocObjectImpl ( pEnv , wrapper ) ;
2007-07-31 19:26:07 +04:00
if ( obj ! = IntPtr . Zero )
{
InvokeHelper ( pEnv , obj , methodID , args , false ) ;
if ( ExceptionCheck ( pEnv ) = = JNI_TRUE )
{
DeleteLocalRef ( pEnv , obj ) ;
obj = IntPtr . Zero ;
}
}
return obj ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static jclass GetObjectClass ( JNIEnv * pEnv , jobject obj )
2004-08-30 19:56:23 +04:00
{
2006-08-17 11:33:38 +04:00
return pEnv - > MakeLocalRef ( IKVM . NativeCode . ikvm . runtime . Util . getClassFromObject ( pEnv - > UnwrapRef ( obj ) ) ) ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static jboolean IsInstanceOf ( JNIEnv * pEnv , jobject obj , jclass clazz )
{
2005-02-02 18:11:26 +03:00
// NOTE if clazz is an interface, this is still the right thing to do
// (i.e. if the object implements the interface, we return true)
2006-08-17 11:33:38 +04:00
object objClass = IKVM . NativeCode . ikvm . runtime . Util . getClassFromObject ( pEnv - > UnwrapRef ( obj ) ) ;
2006-03-27 17:59:59 +04:00
TypeWrapper w1 = TypeWrapper . FromClass ( pEnv - > UnwrapRef ( clazz ) ) ;
TypeWrapper w2 = TypeWrapper . FromClass ( objClass ) ;
2004-09-09 15:17:55 +04:00
return w2 . IsAssignableTo ( w1 ) ? JNI_TRUE : JNI_FALSE ;
}
2004-08-30 19:56:23 +04:00
2008-03-14 12:16:31 +03:00
private static MethodWrapper GetMethodImpl ( TypeWrapper tw , string name , string sig )
{
for ( ; ; )
{
MethodWrapper mw = tw . GetMethodWrapper ( name , sig , true ) ;
if ( mw = = null | | ! mw . IsHideFromReflection )
{
return mw ;
}
tw = mw . DeclaringType . BaseTypeWrapper ;
if ( tw = = null )
{
return null ;
}
}
}
2004-09-09 15:17:55 +04:00
private static jmethodID FindMethodID ( JNIEnv * pEnv , jclass clazz , byte * name , byte * sig , bool isstatic )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
try
2004-08-30 19:56:23 +04:00
{
2006-03-27 17:59:59 +04:00
TypeWrapper wrapper = TypeWrapper . FromClass ( pEnv - > UnwrapRef ( clazz ) ) ;
2004-09-09 15:17:55 +04:00
wrapper . Finish ( ) ;
2005-02-16 14:20:43 +03:00
string methodsig = StringFromUTF8 ( sig ) ;
// don't allow dotted names!
if ( methodsig . IndexOf ( '.' ) < 0 )
2004-08-30 19:56:23 +04:00
{
2008-03-14 12:16:31 +03:00
MethodWrapper mw = GetMethodImpl ( wrapper , StringFromUTF8 ( name ) , methodsig . Replace ( '/' , '.' ) ) ;
2005-02-16 14:20:43 +03:00
if ( mw ! = null )
2004-09-09 15:17:55 +04:00
{
2005-02-16 14:20:43 +03:00
if ( mw . IsStatic = = isstatic )
{
mw . Link ( ) ;
return mw . Cookie ;
}
2004-09-09 15:17:55 +04:00
}
2004-08-30 19:56:23 +04:00
}
2007-04-23 12:24:33 +04:00
SetPendingException ( pEnv , new java . lang . NoSuchMethodError ( string . Format ( "{0}{1}" , StringFromUTF8 ( name ) , StringFromUTF8 ( sig ) . Replace ( '/' , '.' ) ) ) ) ;
2004-08-30 19:56:23 +04:00
}
2004-12-21 17:59:29 +03:00
catch ( RetargetableJavaException x )
{
SetPendingException ( pEnv , x . ToJava ( ) ) ;
}
2004-09-09 15:17:55 +04:00
catch ( Exception x )
{
SetPendingException ( pEnv , x ) ;
}
return IntPtr . Zero ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static jmethodID GetMethodID ( JNIEnv * pEnv , jclass clazz , byte * name , byte * sig )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
return FindMethodID ( pEnv , clazz , name , sig , false ) ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static jobject CallObjectMethodA ( JNIEnv * pEnv , jobject obj , jmethodID methodID , jvalue * args )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
return pEnv - > MakeLocalRef ( InvokeHelper ( pEnv , obj , methodID , args , false ) ) ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static jboolean CallBooleanMethodA ( JNIEnv * pEnv , jobject obj , jmethodID methodID , jvalue * args )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
object o = InvokeHelper ( pEnv , obj , methodID , args , false ) ;
if ( o ! = null )
{
return ( ( bool ) o ) ? JNI_TRUE : JNI_FALSE ;
}
return JNI_FALSE ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static jbyte CallByteMethodA ( JNIEnv * pEnv , jobject obj , jmethodID methodID , jvalue * args )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
object o = InvokeHelper ( pEnv , obj , methodID , args , false ) ;
if ( o ! = null )
{
2005-02-02 18:11:26 +03:00
return ( jbyte ) ( byte ) o ;
2004-09-09 15:17:55 +04:00
}
return 0 ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static jchar CallCharMethodA ( JNIEnv * pEnv , jobject obj , jmethodID methodID , jvalue * args )
{
object o = InvokeHelper ( pEnv , obj , methodID , args , false ) ;
if ( o ! = null )
{
return ( jchar ) ( char ) o ;
}
return 0 ;
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static jshort CallShortMethodA ( JNIEnv * pEnv , jobject obj , jmethodID methodID , jvalue * args )
{
object o = InvokeHelper ( pEnv , obj , methodID , args , false ) ;
if ( o ! = null )
{
return ( jshort ) ( short ) o ;
}
return 0 ;
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static jint CallIntMethodA ( JNIEnv * pEnv , jobject obj , jmethodID methodID , jvalue * args )
{
object o = InvokeHelper ( pEnv , obj , methodID , args , false ) ;
if ( o ! = null )
{
return ( jint ) ( int ) o ;
}
return 0 ;
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static jlong CallLongMethodA ( JNIEnv * pEnv , jobject obj , jmethodID methodID , jvalue * args )
{
object o = InvokeHelper ( pEnv , obj , methodID , args , false ) ;
if ( o ! = null )
{
return ( jlong ) ( long ) o ;
}
return 0 ;
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static jfloat CallFloatMethodA ( JNIEnv * pEnv , jobject obj , jmethodID methodID , jvalue * args )
{
object o = InvokeHelper ( pEnv , obj , methodID , args , false ) ;
if ( o ! = null )
{
return ( jfloat ) ( float ) o ;
}
return 0 ;
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static jdouble CallDoubleMethodA ( JNIEnv * pEnv , jobject obj , jmethodID methodID , jvalue * args )
{
object o = InvokeHelper ( pEnv , obj , methodID , args , false ) ;
if ( o ! = null )
{
return ( jdouble ) ( double ) o ;
}
return 0 ;
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static void CallVoidMethodA ( JNIEnv * pEnv , jobject obj , jmethodID methodID , jvalue * args )
{
InvokeHelper ( pEnv , obj , methodID , args , false ) ;
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static jobject CallNonvirtualObjectMethodA ( JNIEnv * pEnv , jobject obj , jclass clazz , jmethodID methodID , jvalue * args )
{
return pEnv - > MakeLocalRef ( InvokeHelper ( pEnv , obj , methodID , args , true ) ) ;
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static jboolean CallNonvirtualBooleanMethodA ( JNIEnv * pEnv , jobject obj , jclass clazz , jmethodID methodID , jvalue * args )
{
object o = InvokeHelper ( pEnv , obj , methodID , args , true ) ;
if ( o ! = null )
{
return ( ( bool ) o ) ? JNI_TRUE : JNI_FALSE ;
}
return JNI_FALSE ;
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static jbyte CallNonvirtualByteMethodA ( JNIEnv * pEnv , jobject obj , jclass clazz , jmethodID methodID , jvalue * args )
{
object o = InvokeHelper ( pEnv , obj , methodID , args , true ) ;
if ( o ! = null )
{
2005-02-02 18:11:26 +03:00
return ( jbyte ) ( byte ) o ;
2004-09-09 15:17:55 +04:00
}
return 0 ;
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static jchar CallNonvirtualCharMethodA ( JNIEnv * pEnv , jobject obj , jclass clazz , jmethodID methodID , jvalue * args )
{
object o = InvokeHelper ( pEnv , obj , methodID , args , true ) ;
if ( o ! = null )
{
return ( jchar ) ( char ) o ;
}
return 0 ;
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static jshort CallNonvirtualShortMethodA ( JNIEnv * pEnv , jobject obj , jclass clazz , jmethodID methodID , jvalue * args )
{
object o = InvokeHelper ( pEnv , obj , methodID , args , true ) ;
if ( o ! = null )
{
return ( jshort ) ( short ) o ;
}
return 0 ;
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static jint CallNonvirtualIntMethodA ( JNIEnv * pEnv , jobject obj , jclass clazz , jmethodID methodID , jvalue * args )
{
object o = InvokeHelper ( pEnv , obj , methodID , args , true ) ;
if ( o ! = null )
{
return ( jint ) ( int ) o ;
}
return 0 ;
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static jlong CallNonvirtualLongMethodA ( JNIEnv * pEnv , jobject obj , jclass clazz , jmethodID methodID , jvalue * args )
{
object o = InvokeHelper ( pEnv , obj , methodID , args , true ) ;
if ( o ! = null )
{
return ( jlong ) ( long ) o ;
}
return 0 ;
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static jfloat CallNonvirtualFloatMethodA ( JNIEnv * pEnv , jobject obj , jclass clazz , jmethodID methodID , jvalue * args )
{
object o = InvokeHelper ( pEnv , obj , methodID , args , true ) ;
if ( o ! = null )
{
return ( jfloat ) ( float ) o ;
}
return 0 ;
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static jdouble CallNonvirtualDoubleMethodA ( JNIEnv * pEnv , jobject obj , jclass clazz , jmethodID methodID , jvalue * args )
{
object o = InvokeHelper ( pEnv , obj , methodID , args , true ) ;
if ( o ! = null )
{
return ( jdouble ) ( double ) o ;
}
return 0 ;
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static void CallNonvirtualVoidMethodA ( JNIEnv * pEnv , jobject obj , jclass clazz , jmethodID methodID , jvalue * args )
{
InvokeHelper ( pEnv , obj , methodID , args , true ) ;
}
2004-08-30 19:56:23 +04:00
2008-03-14 12:16:31 +03:00
private static FieldWrapper GetFieldImpl ( TypeWrapper tw , string name , string sig )
{
for ( ; ; )
{
FieldWrapper fw = tw . GetFieldWrapper ( name , sig ) ;
if ( fw = = null | | ! fw . IsHideFromReflection )
{
return fw ;
}
tw = fw . DeclaringType . BaseTypeWrapper ;
if ( tw = = null )
{
return null ;
}
}
}
2004-09-09 15:17:55 +04:00
private static jfieldID FindFieldID ( JNIEnv * pEnv , jclass clazz , byte * name , byte * sig , bool isstatic )
{
try
{
2006-03-27 17:59:59 +04:00
TypeWrapper wrapper = TypeWrapper . FromClass ( pEnv - > UnwrapRef ( clazz ) ) ;
2004-09-09 15:17:55 +04:00
wrapper . Finish ( ) ;
2005-02-16 14:20:43 +03:00
string fieldsig = StringFromUTF8 ( sig ) ;
// don't allow dotted names!
if ( fieldsig . IndexOf ( '.' ) < 0 )
2004-09-09 15:17:55 +04:00
{
2008-03-14 12:16:31 +03:00
FieldWrapper fw = GetFieldImpl ( wrapper , StringFromUTF8 ( name ) , fieldsig . Replace ( '/' , '.' ) ) ;
2005-02-16 14:20:43 +03:00
if ( fw ! = null )
2004-09-09 15:17:55 +04:00
{
2005-02-16 14:20:43 +03:00
if ( fw . IsStatic = = isstatic )
{
return fw . Cookie ;
}
2004-09-09 15:17:55 +04:00
}
}
2007-04-23 12:24:33 +04:00
SetPendingException ( pEnv , new java . lang . NoSuchFieldError ( ( isstatic ? "Static" : "Instance" ) + " field '" + StringFromUTF8 ( name ) + "' with signature '" + fieldsig + "' not found in class '" + wrapper . Name + "'" ) ) ;
2004-09-09 15:17:55 +04:00
}
2004-12-21 17:59:29 +03:00
catch ( RetargetableJavaException x )
{
SetPendingException ( pEnv , x . ToJava ( ) ) ;
}
2004-09-09 15:17:55 +04:00
catch ( Exception x )
{
SetPendingException ( pEnv , x ) ;
}
return IntPtr . Zero ;
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static jfieldID GetFieldID ( JNIEnv * pEnv , jclass clazz , byte * name , byte * sig )
{
return FindFieldID ( pEnv , clazz , name , sig , false ) ;
}
2004-08-30 19:56:23 +04:00
2008-08-21 10:40:22 +04:00
private static sun . reflect . FieldAccessor GetFieldAccessor ( jfieldID cookie )
2004-09-09 15:17:55 +04:00
{
2008-08-21 10:40:22 +04:00
return ( sun . reflect . FieldAccessor ) FieldWrapper . FromCookie ( cookie ) . GetFieldAccessorJNI ( ) ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static jobject GetObjectField ( JNIEnv * pEnv , jobject obj , jfieldID fieldID )
2004-08-30 19:56:23 +04:00
{
2008-08-21 10:40:22 +04:00
return pEnv - > MakeLocalRef ( GetFieldAccessor ( fieldID ) . get ( pEnv - > UnwrapRef ( obj ) ) ) ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static jboolean GetBooleanField ( JNIEnv * pEnv , jobject obj , jfieldID fieldID )
2004-08-30 19:56:23 +04:00
{
2008-08-21 10:40:22 +04:00
return GetFieldAccessor ( fieldID ) . getBoolean ( pEnv - > UnwrapRef ( obj ) ) ? JNI_TRUE : JNI_FALSE ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static jbyte GetByteField ( JNIEnv * pEnv , jobject obj , jfieldID fieldID )
2004-08-30 19:56:23 +04:00
{
2008-08-21 10:40:22 +04:00
return ( jbyte ) GetFieldAccessor ( fieldID ) . getByte ( pEnv - > UnwrapRef ( obj ) ) ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static jchar GetCharField ( JNIEnv * pEnv , jobject obj , jfieldID fieldID )
2004-08-30 19:56:23 +04:00
{
2008-08-21 10:40:22 +04:00
return ( jchar ) GetFieldAccessor ( fieldID ) . getChar ( pEnv - > UnwrapRef ( obj ) ) ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static jshort GetShortField ( JNIEnv * pEnv , jobject obj , jfieldID fieldID )
2004-08-30 19:56:23 +04:00
{
2008-08-21 10:40:22 +04:00
return ( jshort ) GetFieldAccessor ( fieldID ) . getShort ( pEnv - > UnwrapRef ( obj ) ) ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static jint GetIntField ( JNIEnv * pEnv , jobject obj , jfieldID fieldID )
2004-08-30 19:56:23 +04:00
{
2008-08-21 10:40:22 +04:00
return ( jint ) GetFieldAccessor ( fieldID ) . getInt ( pEnv - > UnwrapRef ( obj ) ) ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static jlong GetLongField ( JNIEnv * pEnv , jobject obj , jfieldID fieldID )
2004-08-30 19:56:23 +04:00
{
2008-08-21 10:40:22 +04:00
return ( jlong ) GetFieldAccessor ( fieldID ) . getLong ( pEnv - > UnwrapRef ( obj ) ) ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static jfloat GetFloatField ( JNIEnv * pEnv , jobject obj , jfieldID fieldID )
{
2008-08-21 10:40:22 +04:00
return ( jfloat ) GetFieldAccessor ( fieldID ) . getFloat ( pEnv - > UnwrapRef ( obj ) ) ;
2004-09-09 15:17:55 +04:00
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static jdouble GetDoubleField ( JNIEnv * pEnv , jobject obj , jfieldID fieldID )
{
2008-08-21 10:40:22 +04:00
return ( jdouble ) GetFieldAccessor ( fieldID ) . getDouble ( pEnv - > UnwrapRef ( obj ) ) ;
2004-09-09 15:17:55 +04:00
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static void SetObjectField ( JNIEnv * pEnv , jobject obj , jfieldID fieldID , jobject val )
{
2008-08-21 10:40:22 +04:00
GetFieldAccessor ( fieldID ) . set ( pEnv - > UnwrapRef ( obj ) , pEnv - > UnwrapRef ( val ) ) ;
2004-09-09 15:17:55 +04:00
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static void SetBooleanField ( JNIEnv * pEnv , jobject obj , jfieldID fieldID , jboolean val )
{
2008-08-21 10:40:22 +04:00
GetFieldAccessor ( fieldID ) . setBoolean ( pEnv - > UnwrapRef ( obj ) , val ! = JNI_FALSE ) ;
2004-09-09 15:17:55 +04:00
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static void SetByteField ( JNIEnv * pEnv , jobject obj , jfieldID fieldID , jbyte val )
{
2008-08-21 10:40:22 +04:00
GetFieldAccessor ( fieldID ) . setByte ( pEnv - > UnwrapRef ( obj ) , ( byte ) val ) ;
2004-09-09 15:17:55 +04:00
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static void SetCharField ( JNIEnv * pEnv , jobject obj , jfieldID fieldID , jchar val )
{
2008-08-21 10:40:22 +04:00
GetFieldAccessor ( fieldID ) . setChar ( pEnv - > UnwrapRef ( obj ) , ( char ) val ) ;
2004-09-09 15:17:55 +04:00
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static void SetShortField ( JNIEnv * pEnv , jobject obj , jfieldID fieldID , jshort val )
{
2008-08-21 10:40:22 +04:00
GetFieldAccessor ( fieldID ) . setShort ( pEnv - > UnwrapRef ( obj ) , ( short ) val ) ;
2004-09-09 15:17:55 +04:00
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static void SetIntField ( JNIEnv * pEnv , jobject obj , jfieldID fieldID , jint val )
{
2008-08-21 10:40:22 +04:00
GetFieldAccessor ( fieldID ) . setInt ( pEnv - > UnwrapRef ( obj ) , ( int ) val ) ;
2004-09-09 15:17:55 +04:00
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static void SetLongField ( JNIEnv * pEnv , jobject obj , jfieldID fieldID , jlong val )
{
2008-08-21 10:40:22 +04:00
GetFieldAccessor ( fieldID ) . setLong ( pEnv - > UnwrapRef ( obj ) , ( long ) val ) ;
2004-09-09 15:17:55 +04:00
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static void SetFloatField ( JNIEnv * pEnv , jobject obj , jfieldID fieldID , jfloat val )
{
2008-08-21 10:40:22 +04:00
GetFieldAccessor ( fieldID ) . setFloat ( pEnv - > UnwrapRef ( obj ) , ( float ) val ) ;
2004-09-09 15:17:55 +04:00
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static void SetDoubleField ( JNIEnv * pEnv , jobject obj , jfieldID fieldID , jdouble val )
{
2008-08-21 10:40:22 +04:00
GetFieldAccessor ( fieldID ) . setDouble ( pEnv - > UnwrapRef ( obj ) , ( double ) val ) ;
2004-09-09 15:17:55 +04:00
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static jmethodID GetStaticMethodID ( JNIEnv * pEnv , jclass clazz , byte * name , byte * sig )
{
return FindMethodID ( pEnv , clazz , name , sig , true ) ;
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static jobject CallStaticObjectMethodA ( JNIEnv * pEnv , jclass clazz , jmethodID methodID , jvalue * args )
{
return pEnv - > MakeLocalRef ( InvokeHelper ( pEnv , IntPtr . Zero , methodID , args , false ) ) ;
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static jboolean CallStaticBooleanMethodA ( JNIEnv * pEnv , jclass clazz , jmethodID methodID , jvalue * args )
{
object o = InvokeHelper ( pEnv , IntPtr . Zero , methodID , args , false ) ;
if ( o ! = null )
{
return ( ( bool ) o ) ? JNI_TRUE : JNI_FALSE ;
}
return JNI_FALSE ;
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static jbyte CallStaticByteMethodA ( JNIEnv * pEnv , jclass clazz , jmethodID methodID , jvalue * args )
{
object o = InvokeHelper ( pEnv , IntPtr . Zero , methodID , args , false ) ;
if ( o ! = null )
{
2005-02-02 18:11:26 +03:00
return ( jbyte ) ( byte ) o ;
2004-09-09 15:17:55 +04:00
}
return 0 ;
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static jchar CallStaticCharMethodA ( JNIEnv * pEnv , jclass clazz , jmethodID methodID , jvalue * args )
{
object o = InvokeHelper ( pEnv , IntPtr . Zero , methodID , args , false ) ;
if ( o ! = null )
{
return ( jchar ) ( char ) o ;
}
return 0 ;
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static jshort CallStaticShortMethodA ( JNIEnv * pEnv , jclass clazz , jmethodID methodID , jvalue * args )
{
object o = InvokeHelper ( pEnv , IntPtr . Zero , methodID , args , false ) ;
if ( o ! = null )
{
return ( jshort ) ( short ) o ;
}
return 0 ;
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static jint CallStaticIntMethodA ( JNIEnv * pEnv , jclass clazz , jmethodID methodID , jvalue * args )
{
object o = InvokeHelper ( pEnv , IntPtr . Zero , methodID , args , false ) ;
if ( o ! = null )
{
return ( jint ) ( int ) o ;
}
return 0 ;
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static jlong CallStaticLongMethodA ( JNIEnv * pEnv , jclass clazz , jmethodID methodID , jvalue * args )
{
object o = InvokeHelper ( pEnv , IntPtr . Zero , methodID , args , false ) ;
if ( o ! = null )
{
return ( jlong ) ( long ) o ;
}
return 0 ;
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static jfloat CallStaticFloatMethodA ( JNIEnv * pEnv , jclass clazz , jmethodID methodID , jvalue * args )
{
object o = InvokeHelper ( pEnv , IntPtr . Zero , methodID , args , false ) ;
if ( o ! = null )
{
return ( jfloat ) ( float ) o ;
}
return 0 ;
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static jdouble CallStaticDoubleMethodA ( JNIEnv * pEnv , jclass clazz , jmethodID methodID , jvalue * args )
{
object o = InvokeHelper ( pEnv , IntPtr . Zero , methodID , args , false ) ;
if ( o ! = null )
{
return ( jdouble ) ( double ) o ;
}
return 0 ;
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static void CallStaticVoidMethodA ( JNIEnv * pEnv , jclass cls , jmethodID methodID , jvalue * args )
{
InvokeHelper ( pEnv , IntPtr . Zero , methodID , args , false ) ;
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static jfieldID GetStaticFieldID ( JNIEnv * pEnv , jclass clazz , byte * name , byte * sig )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
return FindFieldID ( pEnv , clazz , name , sig , true ) ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static jobject GetStaticObjectField ( JNIEnv * pEnv , jclass clazz , jfieldID fieldID )
{
2008-08-21 10:40:22 +04:00
return pEnv - > MakeLocalRef ( GetFieldAccessor ( fieldID ) . get ( null ) ) ;
2004-09-09 15:17:55 +04:00
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static jboolean GetStaticBooleanField ( JNIEnv * pEnv , jclass clazz , jfieldID fieldID )
{
2008-08-21 10:40:22 +04:00
return GetFieldAccessor ( fieldID ) . getBoolean ( null ) ? JNI_TRUE : JNI_FALSE ;
2004-09-09 15:17:55 +04:00
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static jbyte GetStaticByteField ( JNIEnv * pEnv , jclass clazz , jfieldID fieldID )
{
2008-08-21 10:40:22 +04:00
return ( jbyte ) GetFieldAccessor ( fieldID ) . getByte ( null ) ;
2004-09-09 15:17:55 +04:00
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static jchar GetStaticCharField ( JNIEnv * pEnv , jclass clazz , jfieldID fieldID )
{
2008-08-21 10:40:22 +04:00
return ( jchar ) GetFieldAccessor ( fieldID ) . getChar ( null ) ;
2004-09-09 15:17:55 +04:00
}
internal static jshort GetStaticShortField ( JNIEnv * pEnv , jclass clazz , jfieldID fieldID )
{
2008-08-21 10:40:22 +04:00
return ( jshort ) GetFieldAccessor ( fieldID ) . getShort ( null ) ;
2004-09-09 15:17:55 +04:00
}
internal static jint GetStaticIntField ( JNIEnv * pEnv , jclass clazz , jfieldID fieldID )
2004-08-30 19:56:23 +04:00
{
2008-08-21 10:40:22 +04:00
return ( jint ) GetFieldAccessor ( fieldID ) . getInt ( null ) ;
2004-09-09 15:17:55 +04:00
}
internal static jlong GetStaticLongField ( JNIEnv * pEnv , jclass clazz , jfieldID fieldID )
{
2008-08-21 10:40:22 +04:00
return ( jlong ) GetFieldAccessor ( fieldID ) . getLong ( null ) ;
2004-09-09 15:17:55 +04:00
}
internal static jfloat GetStaticFloatField ( JNIEnv * pEnv , jclass clazz , jfieldID fieldID )
{
2008-08-21 10:40:22 +04:00
return ( jfloat ) GetFieldAccessor ( fieldID ) . getFloat ( null ) ;
2004-09-09 15:17:55 +04:00
}
internal static jdouble GetStaticDoubleField ( JNIEnv * pEnv , jclass clazz , jfieldID fieldID )
{
2008-08-21 10:40:22 +04:00
return ( jdouble ) GetFieldAccessor ( fieldID ) . getDouble ( null ) ;
2004-09-09 15:17:55 +04:00
}
internal static void SetStaticObjectField ( JNIEnv * pEnv , jclass clazz , jfieldID fieldID , jobject val )
{
2008-08-21 10:40:22 +04:00
GetFieldAccessor ( fieldID ) . set ( null , pEnv - > UnwrapRef ( val ) ) ;
2004-09-09 15:17:55 +04:00
}
internal static void SetStaticBooleanField ( JNIEnv * pEnv , jclass clazz , jfieldID fieldID , jboolean val )
{
2008-08-21 10:40:22 +04:00
GetFieldAccessor ( fieldID ) . setBoolean ( null , val ! = JNI_FALSE ) ;
2004-09-09 15:17:55 +04:00
}
internal static void SetStaticByteField ( JNIEnv * pEnv , jclass clazz , jfieldID fieldID , jbyte val )
{
2008-08-21 10:40:22 +04:00
GetFieldAccessor ( fieldID ) . setByte ( null , ( byte ) val ) ;
2004-09-09 15:17:55 +04:00
}
internal static void SetStaticCharField ( JNIEnv * pEnv , jclass clazz , jfieldID fieldID , jchar val )
{
2008-08-21 10:40:22 +04:00
GetFieldAccessor ( fieldID ) . setChar ( null , ( char ) val ) ;
2004-09-09 15:17:55 +04:00
}
internal static void SetStaticShortField ( JNIEnv * pEnv , jclass clazz , jfieldID fieldID , jshort val )
{
2008-08-21 10:40:22 +04:00
GetFieldAccessor ( fieldID ) . setShort ( null , ( short ) val ) ;
2004-09-09 15:17:55 +04:00
}
internal static void SetStaticIntField ( JNIEnv * pEnv , jclass clazz , jfieldID fieldID , jint val )
{
2008-08-21 10:40:22 +04:00
GetFieldAccessor ( fieldID ) . setInt ( null , ( int ) val ) ;
2004-09-09 15:17:55 +04:00
}
internal static void SetStaticLongField ( JNIEnv * pEnv , jclass clazz , jfieldID fieldID , jlong val )
{
2008-08-21 10:40:22 +04:00
GetFieldAccessor ( fieldID ) . setLong ( null , ( long ) val ) ;
2004-09-09 15:17:55 +04:00
}
internal static void SetStaticFloatField ( JNIEnv * pEnv , jclass clazz , jfieldID fieldID , jfloat val )
{
2008-08-21 10:40:22 +04:00
GetFieldAccessor ( fieldID ) . setFloat ( null , ( float ) val ) ;
2004-09-09 15:17:55 +04:00
}
internal static void SetStaticDoubleField ( JNIEnv * pEnv , jclass clazz , jfieldID fieldID , jdouble val )
{
2008-08-21 10:40:22 +04:00
GetFieldAccessor ( fieldID ) . setDouble ( null , ( double ) val ) ;
2004-09-09 15:17:55 +04:00
}
internal static jstring NewString ( JNIEnv * pEnv , jchar * unicode , int len )
{
return pEnv - > MakeLocalRef ( new String ( ( char * ) unicode , 0 , len ) ) ;
}
internal static jint GetStringLength ( JNIEnv * pEnv , jstring str )
{
return ( ( string ) pEnv - > UnwrapRef ( str ) ) . Length ;
}
internal static jchar * GetStringChars ( JNIEnv * pEnv , jstring str , jboolean * isCopy )
{
string s = ( string ) pEnv - > UnwrapRef ( str ) ;
if ( isCopy ! = null )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
* isCopy = JNI_TRUE ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
return ( jchar * ) ( void * ) Marshal . StringToHGlobalUni ( s ) ;
}
internal static void ReleaseStringChars ( JNIEnv * pEnv , jstring str , jchar * chars )
{
Marshal . FreeHGlobal ( ( IntPtr ) ( void * ) chars ) ;
}
internal static jobject NewStringUTF ( JNIEnv * pEnv , byte * psz )
{
return pEnv - > MakeLocalRef ( StringFromUTF8 ( psz ) ) ;
}
internal static jint GetStringUTFLength ( JNIEnv * pEnv , jstring str )
{
return StringUTF8Length ( ( string ) pEnv - > UnwrapRef ( str ) ) ;
}
internal static byte * GetStringUTFChars ( JNIEnv * pEnv , jstring str , jboolean * isCopy )
{
string s = ( string ) pEnv - > UnwrapRef ( str ) ;
byte * buf = ( byte * ) JniMem . Alloc ( StringUTF8Length ( s ) + 1 ) ;
int j = 0 ;
for ( int i = 0 ; i < s . Length ; i + + )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
char ch = s [ i ] ;
if ( ( ch ! = 0 ) & & ( ch < = 0x7F ) )
{
buf [ j + + ] = ( byte ) ch ;
}
else if ( ch < = 0x7FF )
{
buf [ j + + ] = ( byte ) ( ( ch > > 6 ) | 0xC0 ) ;
buf [ j + + ] = ( byte ) ( ( ch & 0x3F ) | 0x80 ) ;
}
else
{
buf [ j + + ] = ( byte ) ( ( ch > > 12 ) | 0xE0 ) ;
buf [ j + + ] = ( byte ) ( ( ( ch > > 6 ) & 0x3F ) | 0x80 ) ;
buf [ j + + ] = ( byte ) ( ( ch & 0x3F ) | 0x80 ) ;
}
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
buf [ j ] = 0 ;
if ( isCopy ! = null )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
* isCopy = JNI_TRUE ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
return buf ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static void ReleaseStringUTFChars ( JNIEnv * pEnv , jstring str , byte * chars )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
JniMem . Free ( ( IntPtr ) ( void * ) chars ) ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static jsize GetArrayLength ( JNIEnv * pEnv , jarray array )
{
return ( ( Array ) pEnv - > UnwrapRef ( array ) ) . Length ;
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static jobject NewObjectArray ( JNIEnv * pEnv , jsize len , jclass clazz , jobject init )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
try
{
// we want to support (non-primitive) value types so we can't cast to object[]
2006-03-27 17:59:59 +04:00
Array array = Array . CreateInstance ( TypeWrapper . FromClass ( pEnv - > UnwrapRef ( clazz ) ) . TypeAsArrayType , len ) ;
2004-09-09 15:17:55 +04:00
object o = pEnv - > UnwrapRef ( init ) ;
if ( o ! = null )
{
for ( int i = 0 ; i < array . Length ; i + + )
{
array . SetValue ( o , i ) ;
}
}
return pEnv - > MakeLocalRef ( array ) ;
}
catch ( ArgumentOutOfRangeException )
{
2007-04-23 12:24:33 +04:00
SetPendingException ( pEnv , new java . lang . NegativeArraySizeException ( ) ) ;
2004-09-09 15:17:55 +04:00
return IntPtr . Zero ;
}
catch ( Exception x )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
SetPendingException ( pEnv , x ) ;
return IntPtr . Zero ;
2004-08-30 19:56:23 +04:00
}
}
2004-09-09 15:17:55 +04:00
internal static jobject GetObjectArrayElement ( JNIEnv * pEnv , jarray array , jsize index )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
try
{
// we want to support (non-primitive) value types so we can't cast to object[]
return pEnv - > MakeLocalRef ( ( ( Array ) pEnv - > UnwrapRef ( array ) ) . GetValue ( index ) ) ;
}
catch ( IndexOutOfRangeException )
{
2007-04-23 12:24:33 +04:00
SetPendingException ( pEnv , new java . lang . ArrayIndexOutOfBoundsException ( ) ) ;
2004-09-09 15:17:55 +04:00
return IntPtr . Zero ;
}
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static void SetObjectArrayElement ( JNIEnv * pEnv , jarray array , jsize index , jobject val )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
try
{
// we want to support (non-primitive) value types so we can't cast to object[]
( ( Array ) pEnv - > UnwrapRef ( array ) ) . SetValue ( pEnv - > UnwrapRef ( val ) , index ) ;
}
catch ( IndexOutOfRangeException )
{
2007-04-23 12:24:33 +04:00
SetPendingException ( pEnv , new java . lang . ArrayIndexOutOfBoundsException ( ) ) ;
2004-09-09 15:17:55 +04:00
}
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static jbooleanArray NewBooleanArray ( JNIEnv * pEnv , jsize len )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
try
{
return pEnv - > MakeLocalRef ( new bool [ len ] ) ;
}
catch ( Exception x )
{
SetPendingException ( pEnv , x ) ;
return IntPtr . Zero ;
}
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static jbyteArray NewByteArray ( JNIEnv * pEnv , jsize len )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
try
{
2005-02-02 18:11:26 +03:00
return pEnv - > MakeLocalRef ( new byte [ len ] ) ;
2004-09-09 15:17:55 +04:00
}
catch ( Exception x )
{
SetPendingException ( pEnv , x ) ;
return IntPtr . Zero ;
}
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static jcharArray NewCharArray ( JNIEnv * pEnv , jsize len )
{
try
{
return pEnv - > MakeLocalRef ( new char [ len ] ) ;
}
catch ( Exception x )
{
SetPendingException ( pEnv , x ) ;
return IntPtr . Zero ;
}
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static jshortArray NewShortArray ( JNIEnv * pEnv , jsize len )
{
try
{
return pEnv - > MakeLocalRef ( new short [ len ] ) ;
}
catch ( Exception x )
{
SetPendingException ( pEnv , x ) ;
return IntPtr . Zero ;
}
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static jintArray NewIntArray ( JNIEnv * pEnv , jsize len )
{
try
{
return pEnv - > MakeLocalRef ( new int [ len ] ) ;
}
catch ( Exception x )
{
SetPendingException ( pEnv , x ) ;
return IntPtr . Zero ;
}
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static jlongArray NewLongArray ( JNIEnv * pEnv , jsize len )
{
try
{
return pEnv - > MakeLocalRef ( new long [ len ] ) ;
}
catch ( Exception x )
{
SetPendingException ( pEnv , x ) ;
return IntPtr . Zero ;
}
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static jfloatArray NewFloatArray ( JNIEnv * pEnv , jsize len )
{
try
{
return pEnv - > MakeLocalRef ( new float [ len ] ) ;
}
catch ( Exception x )
{
SetPendingException ( pEnv , x ) ;
return IntPtr . Zero ;
}
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static jdoubleArray NewDoubleArray ( JNIEnv * pEnv , jsize len )
{
try
{
return pEnv - > MakeLocalRef ( new double [ len ] ) ;
}
catch ( Exception x )
{
SetPendingException ( pEnv , x ) ;
return IntPtr . Zero ;
}
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static jboolean * GetBooleanArrayElements ( JNIEnv * pEnv , jbooleanArray array , jboolean * isCopy )
{
bool [ ] b = ( bool [ ] ) pEnv - > UnwrapRef ( array ) ;
jboolean * p = ( jboolean * ) ( void * ) JniMem . Alloc ( b . Length * 1 ) ;
for ( int i = 0 ; i < b . Length ; i + + )
{
p [ i ] = b [ i ] ? JNI_TRUE : JNI_FALSE ;
}
if ( isCopy ! = null )
{
* isCopy = JNI_TRUE ;
}
return p ;
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static jbyte * GetByteArrayElements ( JNIEnv * pEnv , jbyteArray array , jboolean * isCopy )
{
2005-02-02 18:11:26 +03:00
byte [ ] b = ( byte [ ] ) pEnv - > UnwrapRef ( array ) ;
2004-09-09 15:17:55 +04:00
jbyte * p = ( jbyte * ) ( void * ) JniMem . Alloc ( b . Length * 1 ) ;
for ( int i = 0 ; i < b . Length ; i + + )
{
p [ i ] = ( jbyte ) b [ i ] ;
}
if ( isCopy ! = null )
{
* isCopy = JNI_TRUE ;
}
return p ;
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static jchar * GetCharArrayElements ( JNIEnv * pEnv , jcharArray array , jboolean * isCopy )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
char [ ] b = ( char [ ] ) pEnv - > UnwrapRef ( array ) ;
IntPtr buf = JniMem . Alloc ( b . Length * 2 ) ;
Marshal . Copy ( b , 0 , buf , b . Length ) ;
if ( isCopy ! = null )
{
* isCopy = JNI_TRUE ;
}
return ( jchar * ) ( void * ) buf ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static jshort * GetShortArrayElements ( JNIEnv * pEnv , jshortArray array , jboolean * isCopy )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
short [ ] b = ( short [ ] ) pEnv - > UnwrapRef ( array ) ;
IntPtr buf = JniMem . Alloc ( b . Length * 2 ) ;
Marshal . Copy ( b , 0 , buf , b . Length ) ;
if ( isCopy ! = null )
{
* isCopy = JNI_TRUE ;
}
return ( jshort * ) ( void * ) buf ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static jint * GetIntArrayElements ( JNIEnv * pEnv , jintArray array , jboolean * isCopy )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
int [ ] b = ( int [ ] ) pEnv - > UnwrapRef ( array ) ;
IntPtr buf = JniMem . Alloc ( b . Length * 4 ) ;
Marshal . Copy ( b , 0 , buf , b . Length ) ;
if ( isCopy ! = null )
{
* isCopy = JNI_TRUE ;
}
return ( jint * ) ( void * ) buf ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static jlong * GetLongArrayElements ( JNIEnv * pEnv , jlongArray array , jboolean * isCopy )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
long [ ] b = ( long [ ] ) pEnv - > UnwrapRef ( array ) ;
IntPtr buf = JniMem . Alloc ( b . Length * 8 ) ;
Marshal . Copy ( b , 0 , buf , b . Length ) ;
if ( isCopy ! = null )
{
* isCopy = JNI_TRUE ;
}
return ( jlong * ) ( void * ) buf ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static jfloat * GetFloatArrayElements ( JNIEnv * pEnv , jfloatArray array , jboolean * isCopy )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
float [ ] b = ( float [ ] ) pEnv - > UnwrapRef ( array ) ;
IntPtr buf = JniMem . Alloc ( b . Length * 4 ) ;
Marshal . Copy ( b , 0 , buf , b . Length ) ;
if ( isCopy ! = null )
{
* isCopy = JNI_TRUE ;
}
return ( jfloat * ) ( void * ) buf ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static jdouble * GetDoubleArrayElements ( JNIEnv * pEnv , jdoubleArray array , jboolean * isCopy )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
double [ ] b = ( double [ ] ) pEnv - > UnwrapRef ( array ) ;
IntPtr buf = JniMem . Alloc ( b . Length * 8 ) ;
Marshal . Copy ( b , 0 , buf , b . Length ) ;
if ( isCopy ! = null )
{
* isCopy = JNI_TRUE ;
}
return ( jdouble * ) ( void * ) buf ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static void ReleaseBooleanArrayElements ( JNIEnv * pEnv , jbooleanArray array , jboolean * elems , jint mode )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
if ( mode = = 0 | | mode = = JNI_COMMIT )
{
bool [ ] b = ( bool [ ] ) pEnv - > UnwrapRef ( array ) ;
for ( int i = 0 ; i < b . Length ; i + + )
{
b [ i ] = elems [ i ] ! = JNI_FALSE ;
}
}
if ( mode = = 0 | | mode = = JNI_ABORT )
{
JniMem . Free ( ( IntPtr ) ( void * ) elems ) ;
}
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static void ReleaseByteArrayElements ( JNIEnv * pEnv , jbyteArray array , jbyte * elems , jint mode )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
if ( mode = = 0 | | mode = = JNI_COMMIT )
{
2005-02-02 18:11:26 +03:00
byte [ ] b = ( byte [ ] ) pEnv - > UnwrapRef ( array ) ;
2004-09-09 15:17:55 +04:00
for ( int i = 0 ; i < b . Length ; i + + )
{
2005-02-02 18:11:26 +03:00
b [ i ] = ( byte ) elems [ i ] ;
2004-09-09 15:17:55 +04:00
}
}
if ( mode = = 0 | | mode = = JNI_ABORT )
{
JniMem . Free ( ( IntPtr ) ( void * ) elems ) ;
}
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static void ReleaseCharArrayElements ( JNIEnv * pEnv , jcharArray array , jchar * elems , jint mode )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
if ( mode = = 0 | | mode = = JNI_COMMIT )
{
char [ ] b = ( char [ ] ) pEnv - > UnwrapRef ( array ) ;
Marshal . Copy ( ( IntPtr ) ( void * ) elems , b , 0 , b . Length ) ;
}
if ( mode = = 0 | | mode = = JNI_ABORT )
{
JniMem . Free ( ( IntPtr ) ( void * ) elems ) ;
}
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static void ReleaseShortArrayElements ( JNIEnv * pEnv , jshortArray array , jshort * elems , jint mode )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
if ( mode = = 0 | | mode = = JNI_COMMIT )
{
short [ ] b = ( short [ ] ) pEnv - > UnwrapRef ( array ) ;
Marshal . Copy ( ( IntPtr ) ( void * ) elems , b , 0 , b . Length ) ;
}
if ( mode = = 0 | | mode = = JNI_ABORT )
{
JniMem . Free ( ( IntPtr ) ( void * ) elems ) ;
}
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static void ReleaseIntArrayElements ( JNIEnv * pEnv , jintArray array , jint * elems , jint mode )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
if ( mode = = 0 | | mode = = JNI_COMMIT )
{
int [ ] b = ( int [ ] ) pEnv - > UnwrapRef ( array ) ;
Marshal . Copy ( ( IntPtr ) ( void * ) elems , b , 0 , b . Length ) ;
}
if ( mode = = 0 | | mode = = JNI_ABORT )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
JniMem . Free ( ( IntPtr ) ( void * ) elems ) ;
2004-08-30 19:56:23 +04:00
}
}
2004-09-09 15:17:55 +04:00
internal static void ReleaseLongArrayElements ( JNIEnv * pEnv , jlongArray array , jlong * elems , jint mode )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
if ( mode = = 0 | | mode = = JNI_COMMIT )
{
long [ ] b = ( long [ ] ) pEnv - > UnwrapRef ( array ) ;
Marshal . Copy ( ( IntPtr ) ( void * ) elems , b , 0 , b . Length ) ;
}
if ( mode = = 0 | | mode = = JNI_ABORT )
{
JniMem . Free ( ( IntPtr ) ( void * ) elems ) ;
}
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal static void ReleaseFloatArrayElements ( JNIEnv * pEnv , jfloatArray array , jfloat * elems , jint mode )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
if ( mode = = 0 | | mode = = JNI_COMMIT )
{
float [ ] b = ( float [ ] ) pEnv - > UnwrapRef ( array ) ;
Marshal . Copy ( ( IntPtr ) ( void * ) elems , b , 0 , b . Length ) ;
}
if ( mode = = 0 | | mode = = JNI_ABORT )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
JniMem . Free ( ( IntPtr ) ( void * ) elems ) ;
2004-08-30 19:56:23 +04:00
}
}
2004-09-09 15:17:55 +04:00
internal static void ReleaseDoubleArrayElements ( JNIEnv * pEnv , jdoubleArray array , jdouble * elems , jint mode )
2004-08-17 13:05:21 +04:00
{
2004-09-09 15:17:55 +04:00
if ( mode = = 0 | | mode = = JNI_COMMIT )
{
double [ ] b = ( double [ ] ) pEnv - > UnwrapRef ( array ) ;
Marshal . Copy ( ( IntPtr ) ( void * ) elems , b , 0 , b . Length ) ;
}
if ( mode = = 0 | | mode = = JNI_ABORT )
{
JniMem . Free ( ( IntPtr ) ( void * ) elems ) ;
}
2004-08-17 13:05:21 +04:00
}
2003-01-07 14:40:11 +03:00
2004-09-09 15:17:55 +04:00
internal static void GetBooleanArrayRegion ( JNIEnv * pEnv , IntPtr array , int start , int len , IntPtr buf )
2004-08-17 13:05:21 +04:00
{
2004-09-09 15:17:55 +04:00
try
{
bool [ ] b = ( bool [ ] ) pEnv - > UnwrapRef ( array ) ;
sbyte * p = ( sbyte * ) ( void * ) buf ;
for ( int i = 0 ; i < len ; i + + )
{
* p + + = b [ start + i ] ? JNI_TRUE : JNI_FALSE ;
}
}
catch ( IndexOutOfRangeException )
{
2007-04-23 12:24:33 +04:00
SetPendingException ( pEnv , new java . lang . ArrayIndexOutOfBoundsException ( ) ) ;
2004-09-09 15:17:55 +04:00
}
2004-08-17 13:05:21 +04:00
}
2004-09-09 15:17:55 +04:00
internal static void GetByteArrayRegion ( JNIEnv * pEnv , IntPtr array , int start , int len , IntPtr buf )
2004-08-17 13:05:21 +04:00
{
2004-09-09 15:17:55 +04:00
try
{
2005-02-02 18:11:26 +03:00
byte [ ] b = ( byte [ ] ) pEnv - > UnwrapRef ( array ) ;
byte * p = ( byte * ) ( void * ) buf ;
2004-09-09 15:17:55 +04:00
for ( int i = 0 ; i < len ; i + + )
{
* p + + = b [ start + i ] ;
}
}
catch ( IndexOutOfRangeException )
{
2007-04-23 12:24:33 +04:00
SetPendingException ( pEnv , new java . lang . ArrayIndexOutOfBoundsException ( ) ) ;
2004-09-09 15:17:55 +04:00
}
2004-08-17 13:05:21 +04:00
}
2003-01-17 17:34:33 +03:00
2004-09-09 15:17:55 +04:00
internal static void GetCharArrayRegion ( JNIEnv * pEnv , IntPtr array , int start , int len , IntPtr buf )
2003-01-07 14:40:11 +03:00
{
2004-09-09 15:17:55 +04:00
try
{
char [ ] b = ( char [ ] ) pEnv - > UnwrapRef ( array ) ;
Marshal . Copy ( b , start , buf , len ) ;
}
catch ( ArgumentOutOfRangeException )
{
2007-04-23 12:24:33 +04:00
SetPendingException ( pEnv , new java . lang . ArrayIndexOutOfBoundsException ( ) ) ;
2004-09-09 15:17:55 +04:00
}
2004-08-17 13:05:21 +04:00
}
2004-09-09 15:17:55 +04:00
internal static void GetShortArrayRegion ( JNIEnv * pEnv , IntPtr array , int start , int len , IntPtr buf )
2004-08-17 13:05:21 +04:00
{
2004-09-09 15:17:55 +04:00
try
{
short [ ] b = ( short [ ] ) pEnv - > UnwrapRef ( array ) ;
Marshal . Copy ( b , start , buf , len ) ;
}
catch ( ArgumentOutOfRangeException )
{
2007-04-23 12:24:33 +04:00
SetPendingException ( pEnv , new java . lang . ArrayIndexOutOfBoundsException ( ) ) ;
2004-09-09 15:17:55 +04:00
}
2003-01-07 14:40:11 +03:00
}
2003-01-17 17:34:33 +03:00
2004-09-09 15:17:55 +04:00
internal static void GetIntArrayRegion ( JNIEnv * pEnv , IntPtr array , int start , int len , IntPtr buf )
2004-08-17 13:05:21 +04:00
{
2004-09-09 15:17:55 +04:00
try
{
int [ ] b = ( int [ ] ) pEnv - > UnwrapRef ( array ) ;
Marshal . Copy ( b , start , buf , len ) ;
}
catch ( ArgumentOutOfRangeException )
{
2007-04-23 12:24:33 +04:00
SetPendingException ( pEnv , new java . lang . ArrayIndexOutOfBoundsException ( ) ) ;
2004-09-09 15:17:55 +04:00
}
2004-08-17 13:05:21 +04:00
}
2004-09-09 15:17:55 +04:00
internal static void GetLongArrayRegion ( JNIEnv * pEnv , IntPtr array , int start , int len , IntPtr buf )
2004-08-17 13:05:21 +04:00
{
2004-09-09 15:17:55 +04:00
try
{
long [ ] b = ( long [ ] ) pEnv - > UnwrapRef ( array ) ;
Marshal . Copy ( b , start , buf , len ) ;
}
catch ( ArgumentOutOfRangeException )
{
2007-04-23 12:24:33 +04:00
SetPendingException ( pEnv , new java . lang . ArrayIndexOutOfBoundsException ( ) ) ;
2004-09-09 15:17:55 +04:00
}
2004-08-17 13:05:21 +04:00
}
2003-01-17 17:34:33 +03:00
2004-09-09 15:17:55 +04:00
internal static void GetFloatArrayRegion ( JNIEnv * pEnv , IntPtr array , int start , int len , IntPtr buf )
2004-08-17 13:05:21 +04:00
{
2004-09-09 15:17:55 +04:00
try
{
float [ ] b = ( float [ ] ) pEnv - > UnwrapRef ( array ) ;
Marshal . Copy ( b , start , buf , len ) ;
}
catch ( ArgumentOutOfRangeException )
{
2007-04-23 12:24:33 +04:00
SetPendingException ( pEnv , new java . lang . ArrayIndexOutOfBoundsException ( ) ) ;
2004-09-09 15:17:55 +04:00
}
2004-08-17 13:05:21 +04:00
}
2004-09-09 15:17:55 +04:00
internal static void GetDoubleArrayRegion ( JNIEnv * pEnv , IntPtr array , int start , int len , IntPtr buf )
2004-08-17 13:05:21 +04:00
{
2004-09-09 15:17:55 +04:00
try
{
double [ ] b = ( double [ ] ) pEnv - > UnwrapRef ( array ) ;
Marshal . Copy ( b , start , buf , len ) ;
}
catch ( ArgumentOutOfRangeException )
{
2007-04-23 12:24:33 +04:00
SetPendingException ( pEnv , new java . lang . ArrayIndexOutOfBoundsException ( ) ) ;
2004-09-09 15:17:55 +04:00
}
2004-08-17 13:05:21 +04:00
}
2003-01-07 14:40:11 +03:00
2004-09-09 15:17:55 +04:00
internal static void SetBooleanArrayRegion ( JNIEnv * pEnv , IntPtr array , int start , int len , IntPtr buf )
2004-08-17 13:05:21 +04:00
{
2004-09-09 15:17:55 +04:00
try
{
bool [ ] b = ( bool [ ] ) pEnv - > UnwrapRef ( array ) ;
sbyte * p = ( sbyte * ) ( void * ) buf ;
for ( int i = 0 ; i < len ; i + + )
{
b [ start + i ] = * p + + ! = JNI_FALSE ;
}
}
catch ( IndexOutOfRangeException )
{
2007-04-23 12:24:33 +04:00
SetPendingException ( pEnv , new java . lang . ArrayIndexOutOfBoundsException ( ) ) ;
2004-09-09 15:17:55 +04:00
}
2004-08-17 13:05:21 +04:00
}
2004-09-09 15:17:55 +04:00
internal static void SetByteArrayRegion ( JNIEnv * pEnv , IntPtr array , int start , int len , IntPtr buf )
2004-08-17 13:05:21 +04:00
{
2004-09-09 15:17:55 +04:00
try
{
2005-02-02 18:11:26 +03:00
byte [ ] b = ( byte [ ] ) pEnv - > UnwrapRef ( array ) ;
byte * p = ( byte * ) ( void * ) buf ;
2004-09-09 15:17:55 +04:00
for ( int i = 0 ; i < len ; i + + )
{
b [ start + i ] = * p + + ;
}
}
catch ( IndexOutOfRangeException )
{
2007-04-23 12:24:33 +04:00
SetPendingException ( pEnv , new java . lang . ArrayIndexOutOfBoundsException ( ) ) ;
2004-09-09 15:17:55 +04:00
}
2004-08-17 13:05:21 +04:00
}
2003-01-07 14:40:11 +03:00
2004-09-09 15:17:55 +04:00
internal static void SetCharArrayRegion ( JNIEnv * pEnv , IntPtr array , int start , int len , IntPtr buf )
2004-08-17 13:05:21 +04:00
{
2004-09-09 15:17:55 +04:00
try
{
char [ ] b = ( char [ ] ) pEnv - > UnwrapRef ( array ) ;
Marshal . Copy ( buf , b , start , len ) ;
}
catch ( ArgumentOutOfRangeException )
{
2007-04-23 12:24:33 +04:00
SetPendingException ( pEnv , new java . lang . ArrayIndexOutOfBoundsException ( ) ) ;
2004-09-09 15:17:55 +04:00
}
2004-08-17 13:05:21 +04:00
}
2004-09-09 15:17:55 +04:00
internal static void SetShortArrayRegion ( JNIEnv * pEnv , IntPtr array , int start , int len , IntPtr buf )
2004-08-17 13:05:21 +04:00
{
2004-09-09 15:17:55 +04:00
try
{
short [ ] b = ( short [ ] ) pEnv - > UnwrapRef ( array ) ;
Marshal . Copy ( buf , b , start , len ) ;
}
catch ( ArgumentOutOfRangeException )
{
2007-04-23 12:24:33 +04:00
SetPendingException ( pEnv , new java . lang . ArrayIndexOutOfBoundsException ( ) ) ;
2004-09-09 15:17:55 +04:00
}
2004-08-17 13:05:21 +04:00
}
2003-01-07 14:40:11 +03:00
2004-09-09 15:17:55 +04:00
internal static void SetIntArrayRegion ( JNIEnv * pEnv , IntPtr array , int start , int len , IntPtr buf )
2004-08-17 13:05:21 +04:00
{
2004-09-09 15:17:55 +04:00
try
{
int [ ] b = ( int [ ] ) pEnv - > UnwrapRef ( array ) ;
Marshal . Copy ( buf , b , start , len ) ;
}
catch ( ArgumentOutOfRangeException )
{
2007-04-23 12:24:33 +04:00
SetPendingException ( pEnv , new java . lang . ArrayIndexOutOfBoundsException ( ) ) ;
2004-09-09 15:17:55 +04:00
}
2004-08-17 13:05:21 +04:00
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static void SetLongArrayRegion ( JNIEnv * pEnv , IntPtr array , int start , int len , IntPtr buf )
2004-08-17 13:05:21 +04:00
{
2004-09-09 15:17:55 +04:00
try
{
long [ ] b = ( long [ ] ) pEnv - > UnwrapRef ( array ) ;
Marshal . Copy ( buf , b , start , len ) ;
}
catch ( ArgumentOutOfRangeException )
{
2007-04-23 12:24:33 +04:00
SetPendingException ( pEnv , new java . lang . ArrayIndexOutOfBoundsException ( ) ) ;
2004-09-09 15:17:55 +04:00
}
2004-08-17 13:05:21 +04:00
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static void SetFloatArrayRegion ( JNIEnv * pEnv , IntPtr array , int start , int len , IntPtr buf )
2004-08-17 13:05:21 +04:00
{
2004-09-09 15:17:55 +04:00
try
{
float [ ] b = ( float [ ] ) pEnv - > UnwrapRef ( array ) ;
Marshal . Copy ( buf , b , start , len ) ;
}
catch ( ArgumentOutOfRangeException )
{
2007-04-23 12:24:33 +04:00
SetPendingException ( pEnv , new java . lang . ArrayIndexOutOfBoundsException ( ) ) ;
2004-09-09 15:17:55 +04:00
}
2004-08-17 13:05:21 +04:00
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static void SetDoubleArrayRegion ( JNIEnv * pEnv , IntPtr array , int start , int len , IntPtr buf )
2004-08-17 13:05:21 +04:00
{
2004-09-09 15:17:55 +04:00
try
{
double [ ] b = ( double [ ] ) pEnv - > UnwrapRef ( array ) ;
Marshal . Copy ( buf , b , start , len ) ;
}
catch ( ArgumentOutOfRangeException )
{
2007-04-23 12:24:33 +04:00
SetPendingException ( pEnv , new java . lang . ArrayIndexOutOfBoundsException ( ) ) ;
2004-09-09 15:17:55 +04:00
}
2004-08-17 13:05:21 +04:00
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
[StructLayout(LayoutKind.Sequential)]
unsafe internal struct JNINativeMethod
{
public byte * name ;
public byte * signature ;
public void * fnPtr ;
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static int RegisterNatives ( JNIEnv * pEnv , IntPtr clazz , JNINativeMethod * methods , int nMethods )
2004-08-17 13:05:21 +04:00
{
2004-09-09 15:17:55 +04:00
try
2004-08-30 19:56:23 +04:00
{
2006-03-27 17:59:59 +04:00
TypeWrapper wrapper = TypeWrapper . FromClass ( pEnv - > UnwrapRef ( clazz ) ) ;
2004-09-09 15:17:55 +04:00
wrapper . Finish ( ) ;
for ( int i = 0 ; i < nMethods ; i + + )
2004-08-30 19:56:23 +04:00
{
2005-02-23 15:56:15 +03:00
string methodName = StringFromUTF8 ( methods [ i ] . name ) ;
string methodSig = StringFromUTF8 ( methods [ i ] . signature ) ;
Tracer . Info ( Tracer . Jni , "Registering native method: {0}.{1}{2}, fnPtr = 0x{3:X}" , wrapper . Name , methodName , methodSig , ( ( IntPtr ) methods [ i ] . fnPtr ) . ToInt64 ( ) ) ;
2005-02-16 14:20:43 +03:00
FieldInfo fi = null ;
// don't allow dotted names!
2005-02-23 15:56:15 +03:00
if ( methodSig . IndexOf ( '.' ) < 0 )
2005-02-16 14:20:43 +03:00
{
// TODO this won't work when we're putting the JNI methods in jniproxy.dll
2005-02-23 15:56:15 +03:00
fi = wrapper . TypeAsTBD . GetField ( JNI . METHOD_PTR_FIELD_PREFIX + methodName + methodSig , BindingFlags . Static | BindingFlags . NonPublic ) ;
2005-02-16 14:20:43 +03:00
}
2004-09-09 15:17:55 +04:00
if ( fi = = null )
{
2005-02-23 15:56:15 +03:00
Tracer . Error ( Tracer . Jni , "Failed to register native method: {0}.{1}{2}" , wrapper . Name , methodName , methodSig ) ;
2007-04-23 12:24:33 +04:00
SetPendingException ( pEnv , new java . lang . NoSuchMethodError ( methodName ) ) ;
2004-09-09 15:17:55 +04:00
return JNI_ERR ;
}
fi . SetValue ( null , ( IntPtr ) methods [ i ] . fnPtr ) ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
return JNI_OK ;
}
2004-12-21 17:59:29 +03:00
catch ( RetargetableJavaException x )
{
SetPendingException ( pEnv , x . ToJava ( ) ) ;
return JNI_ERR ;
}
2004-09-09 15:17:55 +04:00
catch ( Exception x )
{
SetPendingException ( pEnv , x ) ;
return JNI_ERR ;
2004-08-30 19:56:23 +04:00
}
2004-08-17 13:05:21 +04:00
}
2004-09-09 15:17:55 +04:00
internal static int UnregisterNatives ( JNIEnv * pEnv , IntPtr clazz )
2004-08-17 13:05:21 +04:00
{
2004-09-09 15:17:55 +04:00
try
2004-08-30 19:56:23 +04:00
{
2006-03-27 17:59:59 +04:00
TypeWrapper wrapper = TypeWrapper . FromClass ( pEnv - > UnwrapRef ( clazz ) ) ;
2004-09-09 15:17:55 +04:00
wrapper . Finish ( ) ;
2004-11-24 13:57:11 +03:00
// TODO this won't work when we're putting the JNI methods in jniproxy.dll
2004-09-09 15:17:55 +04:00
foreach ( FieldInfo fi in wrapper . TypeAsTBD . GetFields ( BindingFlags . Static | BindingFlags . NonPublic ) )
2004-08-30 19:56:23 +04:00
{
2005-02-23 15:56:15 +03:00
string name = fi . Name ;
if ( name . StartsWith ( JNI . METHOD_PTR_FIELD_PREFIX ) )
2004-09-09 15:17:55 +04:00
{
2005-02-23 15:56:15 +03:00
Tracer . Info ( Tracer . Jni , "Unregistering native method: {0}.{1}" , wrapper . Name , name . Substring ( JNI . METHOD_PTR_FIELD_PREFIX . Length ) ) ;
2004-09-09 15:17:55 +04:00
fi . SetValue ( null , IntPtr . Zero ) ;
}
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
return JNI_OK ;
}
2004-12-21 17:59:29 +03:00
catch ( RetargetableJavaException x )
{
SetPendingException ( pEnv , x . ToJava ( ) ) ;
return JNI_ERR ;
}
2004-09-09 15:17:55 +04:00
catch ( Exception x )
{
SetPendingException ( pEnv , x ) ;
return JNI_ERR ;
2004-08-30 19:56:23 +04:00
}
2004-08-17 13:05:21 +04:00
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static int MonitorEnter ( JNIEnv * pEnv , IntPtr obj )
2004-08-17 13:05:21 +04:00
{
2004-09-09 15:17:55 +04:00
try
{
2005-01-03 11:26:21 +03:00
System . Threading . Monitor . Enter ( pEnv - > UnwrapRef ( obj ) ) ;
2004-09-09 15:17:55 +04:00
return JNI_OK ;
}
2004-09-27 14:17:34 +04:00
catch ( Exception x )
2004-09-09 15:17:55 +04:00
{
2004-09-27 14:17:34 +04:00
SetPendingException ( pEnv , x ) ;
2004-09-09 15:17:55 +04:00
return JNI_ERR ;
}
2004-08-17 13:05:21 +04:00
}
2004-09-09 15:17:55 +04:00
internal static int MonitorExit ( JNIEnv * pEnv , IntPtr obj )
2004-08-17 13:05:21 +04:00
{
2004-09-09 15:17:55 +04:00
try
{
System . Threading . Monitor . Exit ( pEnv - > UnwrapRef ( obj ) ) ;
return JNI_OK ;
}
2004-09-27 14:17:34 +04:00
catch ( Exception x )
2004-09-09 15:17:55 +04:00
{
2004-09-27 14:17:34 +04:00
SetPendingException ( pEnv , x ) ;
2004-09-09 15:17:55 +04:00
return JNI_ERR ;
}
2004-08-17 13:05:21 +04:00
}
2004-04-23 15:34:32 +04:00
2004-09-09 15:17:55 +04:00
internal static int GetJavaVM ( JNIEnv * pEnv , JavaVM * * ppJavaVM )
2004-08-17 13:05:21 +04:00
{
2004-09-09 15:17:55 +04:00
* ppJavaVM = JavaVM . pJavaVM ;
2004-08-30 19:56:23 +04:00
return JNI_OK ;
2004-08-17 13:05:21 +04:00
}
2004-09-09 15:17:55 +04:00
internal static void GetStringRegion ( JNIEnv * pEnv , IntPtr str , int start , int len , IntPtr buf )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
string s = ( string ) pEnv - > UnwrapRef ( str ) ;
if ( s ! = null )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
if ( start < 0 | | start > s . Length | | s . Length - start < len )
{
2007-04-23 12:24:33 +04:00
SetPendingException ( pEnv , new java . lang . StringIndexOutOfBoundsException ( ) ) ;
2004-09-09 15:17:55 +04:00
return ;
}
else
{
char * p = ( char * ) ( void * ) buf ;
// TODO isn't there a managed memcpy?
for ( int i = 0 ; i < len ; i + + )
{
* p + + = s [ start + i ] ;
}
return ;
}
2004-08-30 19:56:23 +04:00
}
else
{
2007-04-23 12:24:33 +04:00
SetPendingException ( pEnv , new java . lang . NullPointerException ( ) ) ;
2004-08-30 19:56:23 +04:00
}
}
2004-09-09 15:17:55 +04:00
internal static void GetStringUTFRegion ( JNIEnv * pEnv , IntPtr str , int start , int len , IntPtr buf )
2004-08-17 13:05:21 +04:00
{
2004-09-09 15:17:55 +04:00
string s = ( string ) pEnv - > UnwrapRef ( str ) ;
if ( s ! = null )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
if ( start < 0 | | start > s . Length | | s . Length - start < len )
2004-08-30 19:56:23 +04:00
{
2007-04-23 12:24:33 +04:00
SetPendingException ( pEnv , new java . lang . StringIndexOutOfBoundsException ( ) ) ;
2004-09-09 15:17:55 +04:00
return ;
}
else
{
byte * p = ( byte * ) ( void * ) buf ;
for ( int i = 0 ; i < len ; i + + )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
char ch = s [ start + i ] ;
if ( ( ch ! = 0 ) & & ( ch < = 0x7F ) )
{
* p + + = ( byte ) ch ;
}
else if ( ch < = 0x7FF )
{
* p + + = ( byte ) ( ( ch > > 6 ) | 0xC0 ) ;
* p + + = ( byte ) ( ( ch & 0x3F ) | 0x80 ) ;
}
else
{
* p + + = ( byte ) ( ( ch > > 12 ) | 0xE0 ) ;
* p + + = ( byte ) ( ( ( ch > > 6 ) & 0x3F ) | 0x80 ) ;
* p + + = ( byte ) ( ( ch & 0x3F ) | 0x80 ) ;
}
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
return ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
}
else
{
2007-04-23 12:24:33 +04:00
SetPendingException ( pEnv , new java . lang . NullPointerException ( ) ) ;
2004-08-30 19:56:23 +04:00
}
}
2004-08-17 13:05:21 +04:00
2004-09-09 15:17:55 +04:00
private static int GetPrimitiveArrayElementSize ( Array ar )
2004-08-17 13:05:21 +04:00
{
2004-09-09 15:17:55 +04:00
Type type = ar . GetType ( ) . GetElementType ( ) ;
2005-02-02 18:11:26 +03:00
if ( type = = PrimitiveTypeWrapper . BYTE . TypeAsArrayType | | type = = PrimitiveTypeWrapper . BOOLEAN . TypeAsArrayType )
2004-09-09 15:17:55 +04:00
{
return 1 ;
}
2005-02-02 18:11:26 +03:00
else if ( type = = PrimitiveTypeWrapper . SHORT . TypeAsArrayType | | type = = PrimitiveTypeWrapper . CHAR . TypeAsArrayType )
2004-09-09 15:17:55 +04:00
{
return 2 ;
}
2005-02-02 18:11:26 +03:00
else if ( type = = PrimitiveTypeWrapper . INT . TypeAsArrayType | | type = = PrimitiveTypeWrapper . FLOAT . TypeAsArrayType )
2004-09-09 15:17:55 +04:00
{
return 4 ;
}
2005-02-02 18:11:26 +03:00
else if ( type = = PrimitiveTypeWrapper . LONG . TypeAsArrayType | | type = = PrimitiveTypeWrapper . DOUBLE . TypeAsArrayType )
2004-08-17 13:05:21 +04:00
{
2004-09-09 15:17:55 +04:00
return 8 ;
2004-08-17 13:05:21 +04:00
}
2004-09-09 15:17:55 +04:00
else
2004-08-17 13:05:21 +04:00
{
2004-09-09 15:17:55 +04:00
JVM . CriticalFailure ( "invalid array type" , null ) ;
return 0 ;
2004-08-17 13:05:21 +04:00
}
}
2005-09-01 11:34:53 +04:00
internal static void * GetPrimitiveArrayCritical ( JNIEnv * pEnv , jarray array , jboolean * isCopy )
2004-08-17 13:05:21 +04:00
{
2004-08-30 19:56:23 +04:00
Array ar = ( Array ) pEnv - > UnwrapRef ( array ) ;
2005-09-01 11:34:53 +04:00
if ( pEnv - > criticalArrayHandle1 . Target = = null )
{
pEnv - > criticalArrayHandle1 . Target = ar ;
if ( isCopy ! = null )
{
* isCopy = JNI_FALSE ;
}
return ( void * ) pEnv - > criticalArrayHandle1 . AddrOfPinnedObject ( ) ;
}
if ( pEnv - > criticalArrayHandle2 . Target = = null )
{
pEnv - > criticalArrayHandle2 . Target = ar ;
if ( isCopy ! = null )
{
* isCopy = JNI_FALSE ;
}
return ( void * ) pEnv - > criticalArrayHandle2 . AddrOfPinnedObject ( ) ;
}
2005-02-02 18:11:26 +03:00
// TODO not 64-bit safe (len can overflow)
2004-08-30 19:56:23 +04:00
int len = ar . Length * GetPrimitiveArrayElementSize ( ar ) ;
GCHandle h = GCHandle . Alloc ( ar , GCHandleType . Pinned ) ;
try
{
2004-09-09 15:17:55 +04:00
IntPtr hglobal = JniMem . Alloc ( len ) ;
byte * pdst = ( byte * ) ( void * ) hglobal ;
byte * psrc = ( byte * ) ( void * ) h . AddrOfPinnedObject ( ) ;
2004-08-30 19:56:23 +04:00
// TODO isn't there a managed memcpy?
for ( int i = 0 ; i < len ; i + + )
{
* pdst + + = * psrc + + ;
}
2005-09-01 11:34:53 +04:00
if ( isCopy ! = null )
2004-09-09 15:17:55 +04:00
{
2005-09-01 11:34:53 +04:00
* isCopy = JNI_TRUE ;
2004-09-09 15:17:55 +04:00
}
2005-09-01 11:34:53 +04:00
return ( void * ) hglobal ;
2004-08-30 19:56:23 +04:00
}
finally
{
h . Free ( ) ;
2004-09-09 15:17:55 +04:00
}
2004-08-17 13:05:21 +04:00
}
2005-09-01 11:34:53 +04:00
internal static void ReleasePrimitiveArrayCritical ( JNIEnv * pEnv , jarray array , void * carray , jint mode )
2004-08-30 19:56:23 +04:00
{
2005-09-01 11:34:53 +04:00
Array ar = ( Array ) pEnv - > UnwrapRef ( array ) ;
if ( pEnv - > criticalArrayHandle1 . Target = = ar
& & ( void * ) pEnv - > criticalArrayHandle1 . AddrOfPinnedObject ( ) = = carray )
{
if ( mode = = 0 | | mode = = JNI_ABORT )
{
pEnv - > criticalArrayHandle1 . Target = null ;
}
return ;
}
if ( pEnv - > criticalArrayHandle2 . Target = = ar
& & ( void * ) pEnv - > criticalArrayHandle2 . AddrOfPinnedObject ( ) = = carray )
{
if ( mode = = 0 | | mode = = JNI_ABORT )
{
pEnv - > criticalArrayHandle2 . Target = null ;
}
return ;
}
2004-09-09 15:17:55 +04:00
if ( mode = = 0 | | mode = = JNI_COMMIT )
{
2005-02-02 18:11:26 +03:00
// TODO not 64-bit safe (len can overflow)
2004-09-09 15:17:55 +04:00
int len = ar . Length * GetPrimitiveArrayElementSize ( ar ) ;
GCHandle h = GCHandle . Alloc ( ar , GCHandleType . Pinned ) ;
try
{
byte * pdst = ( byte * ) ( void * ) h . AddrOfPinnedObject ( ) ;
byte * psrc = ( byte * ) ( void * ) carray ;
// TODO isn't there a managed memcpy?
for ( int i = 0 ; i < len ; i + + )
{
* pdst + + = * psrc + + ;
}
}
finally
{
h . Free ( ) ;
}
}
if ( mode = = 0 | | mode = = JNI_ABORT )
2004-08-30 19:56:23 +04:00
{
2005-09-01 11:34:53 +04:00
JniMem . Free ( ( IntPtr ) carray ) ;
2004-08-30 19:56:23 +04:00
}
}
2005-09-01 11:34:53 +04:00
internal static jchar * GetStringCritical ( JNIEnv * pEnv , jstring str , jboolean * isCopy )
2004-09-05 13:37:58 +04:00
{
2004-09-09 15:17:55 +04:00
string s = ( string ) pEnv - > UnwrapRef ( str ) ;
if ( s ! = null )
2004-09-05 13:37:58 +04:00
{
2005-09-01 11:34:53 +04:00
if ( isCopy ! = null )
2004-09-05 13:37:58 +04:00
{
2005-09-01 11:34:53 +04:00
* isCopy = JNI_TRUE ;
2004-09-05 13:37:58 +04:00
}
2005-09-01 11:34:53 +04:00
return ( jchar * ) ( void * ) Marshal . StringToHGlobalUni ( s ) ;
2004-09-05 13:37:58 +04:00
}
2007-04-23 12:24:33 +04:00
SetPendingException ( pEnv , new java . lang . NullPointerException ( ) ) ;
2005-09-01 11:34:53 +04:00
return null ;
2004-09-05 13:37:58 +04:00
}
2005-09-01 11:34:53 +04:00
internal static void ReleaseStringCritical ( JNIEnv * pEnv , jstring str , jchar * cstring )
2004-09-05 13:37:58 +04:00
{
2005-09-01 11:34:53 +04:00
Marshal . FreeHGlobal ( ( IntPtr ) ( void * ) cstring ) ;
2004-09-05 13:37:58 +04:00
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static jweak NewWeakGlobalRef ( JNIEnv * pEnv , jobject obj )
2004-09-05 13:37:58 +04:00
{
2004-09-09 15:17:55 +04:00
object o = pEnv - > UnwrapRef ( obj ) ;
if ( o = = null )
2004-09-05 13:37:58 +04:00
{
2004-09-09 15:17:55 +04:00
return IntPtr . Zero ;
}
lock ( GlobalRefs . weakRefLock )
{
for ( int i = 0 ; i < GlobalRefs . weakRefs . Length ; i + + )
{
2005-05-17 17:18:16 +04:00
if ( ! GlobalRefs . weakRefs [ i ] . IsAllocated )
2004-09-09 15:17:55 +04:00
{
GlobalRefs . weakRefs [ i ] = GCHandle . Alloc ( o , GCHandleType . WeakTrackResurrection ) ;
return ( IntPtr ) ( - ( i | ( 1 < < 30 ) ) ) ;
}
}
int len = GlobalRefs . weakRefs . Length ;
GCHandle [ ] tmp = new GCHandle [ len * 2 ] ;
Array . Copy ( GlobalRefs . weakRefs , 0 , tmp , 0 , len ) ;
tmp [ len ] = GCHandle . Alloc ( o , GCHandleType . WeakTrackResurrection ) ;
GlobalRefs . weakRefs = tmp ;
return ( IntPtr ) ( - ( len | ( 1 < < 30 ) ) ) ;
2004-09-05 13:37:58 +04:00
}
}
2004-08-30 19:56:23 +04:00
2004-09-09 15:17:55 +04:00
internal static void DeleteWeakGlobalRef ( JNIEnv * pEnv , jweak obj )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
int i = obj . ToInt32 ( ) ;
if ( i < 0 )
2004-09-05 13:37:58 +04:00
{
2004-09-09 15:17:55 +04:00
i = - i ;
i - = ( 1 < < 30 ) ;
2004-09-05 13:37:58 +04:00
lock ( GlobalRefs . weakRefLock )
{
2004-09-09 15:17:55 +04:00
GlobalRefs . weakRefs [ i ] . Free ( ) ;
2004-09-05 13:37:58 +04:00
}
}
2004-09-09 15:17:55 +04:00
if ( i > 0 )
2004-09-05 13:37:58 +04:00
{
2004-09-09 15:17:55 +04:00
Debug . Assert ( false , "local ref passed to DeleteWeakGlobalRef" ) ;
2004-09-05 13:37:58 +04:00
}
2004-08-30 19:56:23 +04:00
}
2005-02-02 18:11:26 +03:00
internal static jboolean ExceptionCheck ( JNIEnv * pEnv )
2004-09-05 13:37:58 +04:00
{
2009-05-25 08:01:35 +04:00
ManagedJNIEnv env = pEnv - > GetManagedJNIEnv ( ) ;
return env . pendingException ! = null ? JNI_TRUE : JNI_FALSE ;
2004-09-05 13:37:58 +04:00
}
2004-08-30 19:56:23 +04:00
2004-11-23 20:46:39 +03:00
internal static jobject NewDirectByteBuffer ( JNIEnv * pEnv , IntPtr address , jlong capacity )
2004-08-30 19:56:23 +04:00
{
2004-11-23 20:46:39 +03:00
try
{
if ( capacity < 0 | | capacity > int . MaxValue )
{
2007-04-23 12:24:33 +04:00
SetPendingException ( pEnv , new java . lang . IllegalArgumentException ( "capacity" ) ) ;
2004-11-23 20:46:39 +03:00
return IntPtr . Zero ;
}
2008-08-21 10:05:24 +04:00
return pEnv - > MakeLocalRef ( JVM . NewDirectByteBuffer ( address . ToInt64 ( ) , ( int ) capacity ) ) ;
2004-11-23 20:46:39 +03:00
}
catch ( Exception x )
{
2007-12-19 14:28:09 +03:00
SetPendingException ( pEnv , ikvm . runtime . Util . mapException ( x ) ) ;
2004-11-23 20:46:39 +03:00
return IntPtr . Zero ;
}
}
internal static IntPtr GetDirectBufferAddress ( JNIEnv * pEnv , jobject buf )
{
try
{
2007-12-19 14:28:09 +03:00
return ( IntPtr ) ( ( sun . nio . ch . DirectBuffer ) pEnv - > UnwrapRef ( buf ) ) . address ( ) ;
2004-11-23 20:46:39 +03:00
}
catch ( Exception x )
{
2007-12-19 14:28:09 +03:00
SetPendingException ( pEnv , ikvm . runtime . Util . mapException ( x ) ) ;
2004-11-23 20:46:39 +03:00
return IntPtr . Zero ;
}
}
internal static jlong GetDirectBufferCapacity ( JNIEnv * pEnv , jobject buf )
{
try
{
2007-12-19 14:28:09 +03:00
return ( jlong ) ( long ) ( ( java . nio . Buffer ) pEnv - > UnwrapRef ( buf ) ) . capacity ( ) ;
2004-11-23 20:46:39 +03:00
}
catch ( Exception x )
{
2007-12-19 14:28:09 +03:00
SetPendingException ( pEnv , ikvm . runtime . Util . mapException ( x ) ) ;
2004-11-23 20:46:39 +03:00
return 0 ;
}
2004-08-30 19:56:23 +04:00
}
2007-09-07 09:19:11 +04:00
internal static int GetObjectRefType ( JNIEnv * pEnv , jobject obj )
{
int i = obj . ToInt32 ( ) ;
if ( i > = 0 )
{
return JNILocalRefType ;
}
i = - i ;
if ( ( i & ( 1 < < 30 ) ) ! = 0 )
{
return JNIWeakGlobalRefType ;
}
else
{
return JNIGlobalRefType ;
}
}
2004-09-09 15:17:55 +04:00
internal IntPtr MakeLocalRef ( object obj )
2004-09-05 13:37:58 +04:00
{
2004-09-09 15:17:55 +04:00
if ( obj = = null )
2004-09-05 13:37:58 +04:00
{
2004-09-09 15:17:55 +04:00
return IntPtr . Zero ;
2004-09-05 13:37:58 +04:00
}
2009-05-25 08:01:35 +04:00
ManagedJNIEnv env = GetManagedJNIEnv ( ) ;
object [ ] [ ] localRefs = env . localRefs ;
object [ ] active = localRefs [ env . localRefSlot ] ;
2004-09-09 15:17:55 +04:00
for ( int i = 0 ; i < active . Length ; i + + )
{
if ( active [ i ] = = null )
{
active [ i ] = obj ;
2009-05-25 08:01:35 +04:00
return ( IntPtr ) ( ( env . localRefSlot < < LOCAL_REF_SHIFT ) + i ) ;
2004-09-09 15:17:55 +04:00
}
}
if ( active . Length < LOCAL_REF_BUCKET_SIZE )
{
int i = active . Length ;
object [ ] tmp = new object [ i * 2 ] ;
Array . Copy ( active , 0 , tmp , 0 , i ) ;
2009-05-25 08:01:35 +04:00
active = localRefs [ env . localRefSlot ] = tmp ;
2004-09-09 15:17:55 +04:00
active [ i ] = obj ;
2009-05-25 08:01:35 +04:00
return ( IntPtr ) ( ( env . localRefSlot < < LOCAL_REF_SHIFT ) + i ) ;
2004-09-09 15:17:55 +04:00
}
// if we get here, we're in a native method that most likely is leaking locals refs,
// so we're going to allocate a new bucket and increment localRefSlot, this means that
// any slots that become available in the previous bucket are not going to be reused,
// but since we're assuming that the method is leaking anyway, that isn't a problem
// (it's never a correctness issue, just a resource consumption issue)
2009-05-25 08:01:35 +04:00
env . localRefSlot + + ;
if ( env . localRefSlot = = localRefs . Length )
2004-09-09 15:17:55 +04:00
{
2009-05-25 08:01:35 +04:00
object [ ] [ ] tmp = new object [ env . localRefSlot * 2 ] [ ] ;
Array . Copy ( localRefs , 0 , tmp , 0 , env . localRefSlot ) ;
env . localRefs = localRefs = tmp ;
2004-09-09 15:17:55 +04:00
}
2009-05-25 08:01:35 +04:00
if ( localRefs [ env . localRefSlot ] = = null )
2004-09-09 15:17:55 +04:00
{
2009-05-25 08:01:35 +04:00
localRefs [ env . localRefSlot ] = new object [ LOCAL_REF_BUCKET_SIZE ] ;
2004-09-09 15:17:55 +04:00
}
2009-05-25 08:01:35 +04:00
localRefs [ env . localRefSlot ] [ 0 ] = obj ;
return ( IntPtr ) ( env . localRefSlot < < LOCAL_REF_SHIFT ) ;
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
internal object UnwrapRef ( IntPtr o )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
int i = o . ToInt32 ( ) ;
if ( i > 0 )
2004-08-30 19:56:23 +04:00
{
2009-05-25 08:01:35 +04:00
object [ ] [ ] localRefs = GetManagedJNIEnv ( ) . localRefs ;
2004-09-09 15:17:55 +04:00
return localRefs [ i > > LOCAL_REF_SHIFT ] [ i & LOCAL_REF_MASK ] ;
}
if ( i < 0 )
{
i = - i ;
if ( ( i & ( 1 < < 30 ) ) ! = 0 )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
lock ( GlobalRefs . weakRefLock )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
return GlobalRefs . weakRefs [ i - ( 1 < < 30 ) ] . Target ;
2004-08-30 19:56:23 +04:00
}
}
2004-09-09 15:17:55 +04:00
else
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
lock ( GlobalRefs . globalRefs )
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
return GlobalRefs . globalRefs [ i - 1 ] ;
2004-08-30 19:56:23 +04:00
}
}
}
2004-09-09 15:17:55 +04:00
return null ;
2004-08-30 19:56:23 +04:00
}
}
2004-09-09 15:17:55 +04:00
class JniMem
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
internal static IntPtr Alloc ( int cb )
2004-09-05 13:37:58 +04:00
{
2004-09-09 15:17:55 +04:00
return Marshal . AllocHGlobal ( cb ) ;
2004-09-05 13:37:58 +04:00
}
2004-09-09 15:17:55 +04:00
internal static void Free ( IntPtr p )
2004-09-05 13:37:58 +04:00
{
2004-09-09 15:17:55 +04:00
Marshal . FreeHGlobal ( p ) ;
2004-09-05 13:37:58 +04:00
}
2004-08-30 19:56:23 +04:00
}
2004-09-09 15:17:55 +04:00
unsafe class TlsHack
2004-08-30 19:56:23 +04:00
{
2004-09-09 15:17:55 +04:00
[ThreadStatic]
internal static JNIEnv * pJNIEnv ;
2004-08-30 19:56:23 +04:00
}
2003-01-07 14:40:11 +03:00
}