44using System . Diagnostics ;
55using System . Collections . Generic ;
66using System . Text ;
7+ using System . Runtime . InteropServices ;
78
89namespace Java . Interop
910{
@@ -44,22 +45,13 @@ static unsafe JniObjectReference TryFindClass (string classname, bool throwOnErr
4445 throw new ArgumentException ( "'classname' cannot be a zero-length string." , nameof ( classname ) ) ;
4546
4647 var info = JniEnvironment . CurrentInfo ;
47- #if FEATURE_JNIENVIRONMENT_JI_PINVOKES
48- IntPtr thrown ;
49- var c = NativeMethods . java_interop_jnienv_find_class ( info . EnvironmentPointer , out thrown , classname ) ;
50- if ( thrown == IntPtr . Zero ) {
48+ #if FEATURE_JNIENVIRONMENT_JI_PINVOKES || FEATURE_JNIENVIRONMENT_JI_FUNCTION_POINTERS
49+ if ( TryRawFindClass ( info . EnvironmentPointer , classname , out var c , out var thrown ) ) {
5150 var r = new JniObjectReference ( c , JniObjectReferenceType . Local ) ;
5251 JniEnvironment . LogCreateLocalRef ( r ) ;
5352 return r ;
5453 }
55-
56- // If the Java-side exception stack trace is *lost* a'la 89a5a229,
57- // change `false` to `true` and rebuild+re-run.
58- #if false
59- NativeMethods . java_interop_jnienv_exception_describe ( info . EnvironmentPointer ) ;
60- #endif
61-
62- NativeMethods . java_interop_jnienv_exception_clear ( info . EnvironmentPointer ) ;
54+ RawExceptionClear ( info . EnvironmentPointer ) ;
6355
6456 var findClassThrown = new JniObjectReference ( thrown , JniObjectReferenceType . Local ) ;
6557 LogCreateLocalRef ( findClassThrown ) ;
@@ -70,18 +62,18 @@ static unsafe JniObjectReference TryFindClass (string classname, bool throwOnErr
7062 var __args = stackalloc JniArgumentValue [ 1 ] ;
7163 __args [ 0 ] = new JniArgumentValue ( java ) ;
7264
73- c = NativeMethods . java_interop_jnienv_call_object_method_a ( info . EnvironmentPointer , out thrown , info . Runtime . ClassLoader . Handle , info . Runtime . ClassLoader_LoadClass . ID , ( IntPtr ) __args ) ;
65+ c = RawCallObjectMethodA ( info . EnvironmentPointer , out thrown , info . Runtime . ClassLoader . Handle , info . Runtime . ClassLoader_LoadClass . ID , ( IntPtr ) __args ) ;
7466 JniObjectReference . Dispose ( ref java ) ;
7567 if ( thrown == IntPtr . Zero ) {
7668 ( pendingException as IJavaPeerable ) ? . Dispose ( ) ;
7769 var r = new JniObjectReference ( c , JniObjectReferenceType . Local ) ;
7870 JniEnvironment . LogCreateLocalRef ( r ) ;
7971 return r ;
8072 }
81- NativeMethods . java_interop_jnienv_exception_clear ( info . EnvironmentPointer ) ;
73+ RawExceptionClear ( info . EnvironmentPointer ) ;
8274
8375 if ( pendingException != null ) {
84- NativeMethods . java_interop_jnienv_delete_local_ref ( info . EnvironmentPointer , thrown ) ;
76+ JniEnvironment . References . RawDeleteLocalRef ( info . EnvironmentPointer , thrown ) ;
8577 }
8678 else {
8779 var loadClassThrown = new JniObjectReference ( thrown , JniObjectReferenceType . Local ) ;
@@ -95,7 +87,7 @@ static unsafe JniObjectReference TryFindClass (string classname, bool throwOnErr
9587 return default ;
9688 }
9789 throw pendingException ! ;
98- #endif // !FEATURE_JNIENVIRONMENT_JI_PINVOKES
90+ #endif // !( FEATURE_JNIENVIRONMENT_JI_PINVOKES || FEATURE_JNIENVIRONMENT_JI_FUNCTION_POINTERS)
9991#if FEATURE_JNIOBJECTREFERENCE_SAFEHANDLES
10092 var c = info . Invoker . FindClass ( info . EnvironmentPointer , classname ) ;
10193 var thrown = info . Invoker . ExceptionOccurred ( info . EnvironmentPointer ) ;
@@ -137,6 +129,59 @@ static unsafe JniObjectReference TryFindClass (string classname, bool throwOnErr
137129#endif // !FEATURE_JNIOBJECTREFERENCE_SAFEHANDLES
138130 }
139131
132+ static bool TryRawFindClass ( IntPtr env , string classname , out IntPtr klass , out IntPtr thrown )
133+ {
134+ #if FEATURE_JNIENVIRONMENT_JI_PINVOKES
135+ klass = NativeMethods . java_interop_jnienv_find_class ( env , out thrown , classname ) ;
136+ if ( thrown == IntPtr . Zero ) {
137+ return true ;
138+ }
139+ #endif // !FEATURE_JNIENVIRONMENT_JI_PINVOKES
140+ #if FEATURE_JNIENVIRONMENT_JI_FUNCTION_POINTERS
141+ var _classname_ptr = Marshal . StringToCoTaskMemUTF8 ( classname ) ;
142+ klass = JniNativeMethods . FindClass ( env , _classname_ptr ) ;
143+ thrown = JniNativeMethods . ExceptionOccurred ( env ) ;
144+ Marshal . ZeroFreeCoTaskMemUTF8 ( _classname_ptr ) ;
145+ if ( thrown == IntPtr . Zero ) {
146+ return true ;
147+ }
148+ #endif // !FEATURE_JNIENVIRONMENT_JI_FUNCTION_POINTERS
149+ return false ;
150+ }
151+
152+ static void RawExceptionClear ( IntPtr env )
153+ {
154+ #if FEATURE_JNIENVIRONMENT_JI_PINVOKES
155+ // If the Java-side exception stack trace is *lost* a'la 89a5a229,
156+ // change `false` to `true` and rebuild+re-run.
157+ #if false
158+ NativeMethods . java_interop_jnienv_exception_describe ( env ) ;
159+ #endif // FEATURE_JNIENVIRONMENT_JI_PINVOKES
160+
161+ NativeMethods . java_interop_jnienv_exception_clear ( env ) ;
162+ #elif FEATURE_JNIENVIRONMENT_JI_FUNCTION_POINTERS
163+ // If the Java-side exception stack trace is *lost* a'la 89a5a229,
164+ // change `false` to `true` and rebuild+re-run.
165+ #if false
166+ JniNativeMethods . ExceptionDescribe ( env ) ;
167+ #endif
168+ JniNativeMethods . ExceptionClear ( env ) ;
169+ #endif // FEATURE_JNIENVIRONMENT_JI_FUNCTION_POINTERS
170+ }
171+
172+ static IntPtr RawCallObjectMethodA ( IntPtr env , out IntPtr thrown , IntPtr instance , IntPtr jmethodID , IntPtr args )
173+ {
174+ #if FEATURE_JNIENVIRONMENT_JI_PINVOKES
175+ return NativeMethods . java_interop_jnienv_call_object_method_a ( env , out thrown , instance , jmethodID , args ) ;
176+ #elif FEATURE_JNIENVIRONMENT_JI_FUNCTION_POINTERS
177+ var r = JniNativeMethods . CallObjectMethodA ( env , instance , jmethodID , args ) ;
178+ thrown = JniNativeMethods . ExceptionOccurred ( env ) ;
179+ return r ;
180+ #else // FEATURE_JNIENVIRONMENT_JI_FUNCTION_POINTERS
181+ return IntPtr . Zero ;
182+ #endif // FEATURE_JNIENVIRONMENT_JI_FUNCTION_POINTERS
183+ }
184+
140185#if NET
141186 public static bool TryFindClass ( string classname , out JniObjectReference instance )
142187 {
0 commit comments