@@ -111,13 +111,13 @@ static void GenerateFile (TextWriter o)
111
111
o . WriteLine ( ) ;
112
112
o . WriteLine ( "using JNIEnvPtr = System.IntPtr;" ) ;
113
113
o . WriteLine ( ) ;
114
- o . WriteLine ( "#if FEATURE_JNIENVIRONMENT_JI_INTPTRS || FEATURE_JNIENVIRONMENT_JI_PINVOKES" ) ;
114
+ o . WriteLine ( "#if FEATURE_JNIENVIRONMENT_JI_INTPTRS || FEATURE_JNIENVIRONMENT_JI_PINVOKES || FEATURE_JNIENVIRONMENT_JI_FUNCTION_POINTERS " ) ;
115
115
o . WriteLine ( "\t using jinstanceFieldID = System.IntPtr;" ) ;
116
116
o . WriteLine ( "\t using jstaticFieldID = System.IntPtr;" ) ;
117
117
o . WriteLine ( "\t using jinstanceMethodID = System.IntPtr;" ) ;
118
118
o . WriteLine ( "\t using jstaticMethodID = System.IntPtr;" ) ;
119
119
o . WriteLine ( "\t using jobject = System.IntPtr;" ) ;
120
- o . WriteLine ( "#endif // FEATURE_JNIENVIRONMENT_JI_INTPTRS || FEATURE_JNIENVIRONMENT_JI_PINVOKES" ) ;
120
+ o . WriteLine ( "#endif // FEATURE_JNIENVIRONMENT_JI_INTPTRS || FEATURE_JNIENVIRONMENT_JI_PINVOKES || FEATURE_JNIENVIRONMENT_JI_FUNCTION_POINTERS " ) ;
121
121
o . WriteLine ( ) ;
122
122
o . WriteLine ( "namespace Java.Interop {" ) ;
123
123
GenerateJniNativeInterface ( o ) ;
@@ -126,6 +126,7 @@ static void GenerateFile (TextWriter o)
126
126
WriteSection ( o , HandleStyle . JIIntPtr , "FEATURE_JNIENVIRONMENT_JI_INTPTRS" , "Java.Interop.JIIntPtrs" ) ;
127
127
WriteSection ( o , HandleStyle . JIIntPtrPinvokeWithErrors , "FEATURE_JNIENVIRONMENT_JI_PINVOKES" , "Java.Interop.JIPinvokes" ) ;
128
128
WriteSection ( o , HandleStyle . XAIntPtr , "FEATURE_JNIENVIRONMENT_XA_INTPTRS" , "Java.Interop.XAIntPtrs" ) ;
129
+ WriteSection ( o , HandleStyle . JIFunctionPtrWithErrors , "FEATURE_JNIENVIRONMENT_JI_FUNCTION_POINTERS" , "Java.Interop.JIFunctionPointers" ) ;
129
130
}
130
131
131
132
static void WriteSection ( TextWriter o , HandleStyle style , string define , string specificNamespace )
@@ -139,7 +140,7 @@ static void WriteSection (TextWriter o, HandleStyle style, string define, string
139
140
o . WriteLine ( "#endif" ) ;
140
141
o . WriteLine ( "{" ) ;
141
142
o . WriteLine ( ) ;
142
- if ( style != HandleStyle . JIIntPtrPinvokeWithErrors ) {
143
+ if ( style != HandleStyle . JIIntPtrPinvokeWithErrors && style != HandleStyle . JIFunctionPtrWithErrors ) {
143
144
GenerateDelegates ( o , style ) ;
144
145
o . WriteLine ( ) ;
145
146
}
@@ -166,26 +167,56 @@ static void GenerateDelegates (TextWriter o, HandleStyle style)
166
167
167
168
static void GenerateJniNativeInterface ( TextWriter o )
168
169
{
170
+ o . WriteLine ( "#pragma warning disable 0649 // Field is assigned to, and will always have its default value `null`; ignore as it'll be set in native code." ) ;
171
+ o . WriteLine ( "#pragma warning disable 0169 // Field never used; ignore since these fields make the structure have the right layout." ) ;
172
+ o . WriteLine ( ) ;
173
+
169
174
o . WriteLine ( "#if FEATURE_JNIENVIRONMENT_SAFEHANDLES || FEATURE_JNIENVIRONMENT_JI_INTPTRS || FEATURE_JNIENVIRONMENT_XA_INTPTRS" ) ;
170
175
o . WriteLine ( "\t [StructLayout (LayoutKind.Sequential)]" ) ;
171
176
o . WriteLine ( "\t partial struct JniNativeInterfaceStruct {" ) ;
172
177
o . WriteLine ( ) ;
173
178
174
179
int maxName = JNIEnvEntries . Max ( e => e . Name . Length ) ;
175
180
176
- o . WriteLine ( "#pragma warning disable 0649 // Field is assigned to, and will always have its default value `null`; ignore as it'll be set in native code." ) ;
177
- o . WriteLine ( "#pragma warning disable 0169 // Field never used; ignore since these fields make the structure have the right layout." ) ;
178
-
179
181
for ( int i = 0 ; i < 4 ; i ++ )
180
182
o . WriteLine ( "\t \t private IntPtr reserved{0}; // void*" , i ) ;
181
183
182
184
foreach ( var e in JNIEnvEntries ) {
183
185
o . WriteLine ( "\t \t public IntPtr {0};{1} // {2}" , e . Name , new string ( ' ' , maxName - e . Name . Length ) , e . Prototype ) ;
184
186
}
185
- o . WriteLine ( "#pragma warning restore 0169" ) ;
186
- o . WriteLine ( "#pragma warning restore 0649" ) ;
187
187
o . WriteLine ( "\t }" ) ;
188
188
o . WriteLine ( "#endif // FEATURE_JNIENVIRONMENT_SAFEHANDLES || FEATURE_JNIENVIRONMENT_JI_INTPTRS || FEATURE_JNIENVIRONMENT_XA_INTPTRS" ) ;
189
+ o . WriteLine ( ) ;
190
+
191
+ o . WriteLine ( "#if FEATURE_JNIENVIRONMENT_JI_FUNCTION_POINTERS" ) ;
192
+ o . WriteLine ( "\t [StructLayout (LayoutKind.Sequential)]" ) ;
193
+ o . WriteLine ( "\t unsafe partial struct JNIEnv {" ) ;
194
+
195
+ for ( int i = 0 ; i < 4 ; i ++ )
196
+ o . WriteLine ( "\t \t private IntPtr reserved{0}; // void*" , i ) ;
197
+
198
+ foreach ( var e in JNIEnvEntries ) {
199
+ if ( e . Parameters . Length > 0 &&
200
+ "va_list" == e . Parameters [ e . Parameters . Length - 1 ] . Type . GetManagedType ( HandleStyle . JIFunctionPtrWithErrors , isReturn : false , isPinvoke : true ) ) {
201
+ o . WriteLine ( "\t \t public IntPtr {0};{1} // {2}" , e . Name , new string ( ' ' , maxName - e . Name . Length ) , e . Prototype ) ;
202
+ continue ;
203
+ }
204
+ o . Write ( "\t \t public delegate* unmanaged <IntPtr /* env */" ) ;
205
+ foreach ( var p in e . Parameters ) {
206
+ o . Write ( ", " ) ;
207
+ o . Write ( p . Type . GetMarshalType ( HandleStyle . JIFunctionPtrWithErrors , isReturn : false , isPinvoke : true ) ) ;
208
+ o . Write ( $ " /* { p . Name } */") ;
209
+ }
210
+ o . Write ( ", " ) ;
211
+ o . Write ( e . ReturnType . GetMarshalType ( HandleStyle . JIFunctionPtrWithErrors , isReturn : true , isPinvoke : true ) ) ;
212
+ o . WriteLine ( $ "> { e . Name } ;") ;
213
+ }
214
+ o . WriteLine ( "\t }" ) ;
215
+ o . WriteLine ( "#endif // FEATURE_JNIENVIRONMENT_JI_FUNCTION_POINTERS" ) ;
216
+
217
+ o . WriteLine ( ) ;
218
+ o . WriteLine ( "#pragma warning restore 0169" ) ;
219
+ o . WriteLine ( "#pragma warning restore 0649" ) ;
189
220
}
190
221
191
222
static string Initialize ( JniFunction e , string prefix , string delegateType )
@@ -379,9 +410,12 @@ static void GenerateJniEnv (TextWriter o, string type, string visibility, Handle
379
410
o . WriteLine ( ")" ) ;
380
411
o . WriteLine ( "\t \t {" ) ;
381
412
NullCheckParameters ( o , entry . Parameters , style ) ;
413
+ PrepareParameters ( o , entry . Parameters , style ) ;
382
414
if ( style == HandleStyle . JIIntPtrPinvokeWithErrors ) {
383
415
if ( entry . Throws )
384
416
o . WriteLine ( "\t \t \t IntPtr thrown;" ) ;
417
+ } else if ( style == HandleStyle . JIFunctionPtrWithErrors ) {
418
+ o . WriteLine ( $ "\t \t \t IntPtr __env = JniEnvironment.EnvironmentPointer;") ;
385
419
} else {
386
420
o . WriteLine ( "\t \t \t var __info = JniEnvironment.CurrentInfo;" ) ;
387
421
}
@@ -392,17 +426,27 @@ static void GenerateJniEnv (TextWriter o, string type, string visibility, Handle
392
426
o . Write ( "NativeMethods.{0} (JniEnvironment.EnvironmentPointer{1}" ,
393
427
GetPinvokeName ( entry . Name ) ,
394
428
entry . Throws ? ", out thrown" : "" ) ;
429
+ } else if ( style == HandleStyle . JIFunctionPtrWithErrors ) {
430
+ o . Write ( $ "(*((JNIEnv**)__env))->{ entry . Name } (__env") ;
395
431
} else {
396
432
o . Write ( "__info.Invoker.{0} (__info.EnvironmentPointer" , entry . Name ) ;
397
433
}
398
434
for ( int i = 0 ; i < entry . Parameters . Length ; i ++ ) {
399
435
var p = entry . Parameters [ i ] ;
400
436
o . Write ( ", " ) ;
401
- if ( p . Type . GetManagedType ( style , isReturn : false ) . StartsWith ( "out " , StringComparison . Ordinal ) )
437
+ var needOut = p . Type . GetManagedType ( style , isReturn : false ) . StartsWith ( "out " , StringComparison . Ordinal ) ;
438
+ if ( needOut && style == HandleStyle . JIFunctionPtrWithErrors ) {
439
+ o . Write ( "&" ) ;
440
+ } else if ( needOut ) {
402
441
o . Write ( "out " ) ;
442
+ }
403
443
o . Write ( p . Type . GetManagedToMarshalExpression ( style , Escape ( entry . Parameters [ i ] . Name ) ) ) ;
404
444
}
405
445
o . WriteLine ( ");" ) ;
446
+ if ( style == HandleStyle . JIFunctionPtrWithErrors && entry . Throws ) {
447
+ o . WriteLine ( "\t \t \t IntPtr thrown = (*((JNIEnv**)__env))->ExceptionOccurred (__env);" ) ;
448
+ }
449
+ CleanupParameters ( o , entry . Parameters , style ) ;
406
450
RaiseException ( o , entry , style ) ;
407
451
if ( is_void ) {
408
452
} else {
@@ -436,14 +480,38 @@ static void NullCheckParameters (TextWriter o, ParamInfo[] ps, HandleStyle style
436
480
o . WriteLine ( ) ;
437
481
}
438
482
483
+ static void PrepareParameters ( TextWriter o , ParamInfo [ ] ps , HandleStyle style )
484
+ {
485
+ bool haveChecks = false ;
486
+ foreach ( var e in ps ) {
487
+ foreach ( var s in e . Type . GetManagedToMarshalPrepareStatements ( style , Escape ( e . Name ) ) ) {
488
+ haveChecks = true ;
489
+ o . WriteLine ( $ "\t \t \t { s } ") ;
490
+ }
491
+ }
492
+ if ( haveChecks )
493
+ o . WriteLine ( ) ;
494
+ }
495
+
496
+ static void CleanupParameters ( TextWriter o , ParamInfo [ ] ps , HandleStyle style )
497
+ {
498
+ foreach ( var e in ps ) {
499
+ foreach ( var s in e . Type . GetManagedToMarshalCleanupStatements ( style , Escape ( e . Name ) ) ) {
500
+ o . WriteLine ( $ "\t \t \t { s } ") ;
501
+ }
502
+ }
503
+ }
504
+
439
505
static void RaiseException ( TextWriter o , JniFunction entry , HandleStyle style )
440
506
{
441
507
if ( ! entry . Throws )
442
508
return ;
443
509
444
510
o . WriteLine ( ) ;
445
511
o . WriteLine ( "\t \t \t Exception __e = JniEnvironment.GetExceptionForLastThrowable ({0});" ,
446
- style == HandleStyle . JIIntPtrPinvokeWithErrors ? "thrown" : "" ) ;
512
+ ( style == HandleStyle . JIIntPtrPinvokeWithErrors || style == HandleStyle . JIFunctionPtrWithErrors )
513
+ ? "thrown"
514
+ : "" ) ;
447
515
o . WriteLine ( "\t \t \t if (__e != null)" ) ;
448
516
o . WriteLine ( "\t \t \t \t ExceptionDispatchInfo.Capture (__e).Throw ();" ) ;
449
517
o . WriteLine ( ) ;
@@ -728,6 +796,9 @@ public virtual string[] VerifyParameter (HandleStyle style, string variable)
728
796
{
729
797
return new string [ 0 ] ;
730
798
}
799
+
800
+ public virtual string [ ] GetManagedToMarshalPrepareStatements ( HandleStyle style , string variable ) => Array . Empty < string > ( ) ;
801
+ public virtual string [ ] GetManagedToMarshalCleanupStatements ( HandleStyle style , string variable ) => Array . Empty < string > ( ) ;
731
802
}
732
803
733
804
class BuiltinTypeInfo : TypeInfo {
@@ -822,6 +893,9 @@ public StringTypeInfo (string jni)
822
893
823
894
public override string GetMarshalType ( HandleStyle style , bool isReturn , bool isPinvoke )
824
895
{
896
+ if ( style == HandleStyle . JIFunctionPtrWithErrors && isPinvoke ) {
897
+ return "IntPtr" ;
898
+ }
825
899
return "string" ;
826
900
}
827
901
@@ -830,6 +904,16 @@ public override string GetManagedType (HandleStyle style, bool isReturn, bool is
830
904
return "string" ;
831
905
}
832
906
907
+ public override string GetManagedToMarshalExpression ( HandleStyle style , string variable )
908
+ {
909
+ switch ( style ) {
910
+ case HandleStyle . JIFunctionPtrWithErrors :
911
+ return $ "_{ variable } _ptr";
912
+ default :
913
+ return variable ;
914
+ }
915
+ }
916
+
833
917
public override string [ ] GetMarshalToManagedStatements ( HandleStyle style , string variable , JniFunction entry )
834
918
{
835
919
switch ( style ) {
@@ -841,6 +925,7 @@ public override string[] GetMarshalToManagedStatements (HandleStyle style, strin
841
925
} ;
842
926
case HandleStyle . JIIntPtr :
843
927
case HandleStyle . JIIntPtrPinvokeWithErrors :
928
+ case HandleStyle . JIFunctionPtrWithErrors :
844
929
return new [ ] {
845
930
string . Format ( "JniEnvironment.LogCreateLocalRef ({0});" , variable ) ,
846
931
string . Format ( "return new JniObjectReference ({0}, JniObjectReferenceType.Local);" , variable ) ,
@@ -859,6 +944,30 @@ public override string[] VerifyParameter (HandleStyle style, string variable)
859
944
string . Format ( "\t throw new ArgumentNullException (\" {0}\" );" , variableName ) ,
860
945
} ;
861
946
}
947
+
948
+ public override string [ ] GetManagedToMarshalPrepareStatements ( HandleStyle style , string variable )
949
+ {
950
+ switch ( style ) {
951
+ case HandleStyle . JIFunctionPtrWithErrors :
952
+ return new [ ] {
953
+ $ "var _{ variable } _ptr = Marshal.StringToCoTaskMemUTF8 ({ variable } );",
954
+ } ;
955
+ default :
956
+ return base . GetManagedToMarshalPrepareStatements ( style , variable ) ;
957
+ }
958
+ }
959
+
960
+ public override string [ ] GetManagedToMarshalCleanupStatements ( HandleStyle style , string variable )
961
+ {
962
+ switch ( style ) {
963
+ case HandleStyle . JIFunctionPtrWithErrors :
964
+ return new [ ] {
965
+ $ "Marshal.ZeroFreeCoTaskMemUTF8 (_{ variable } _ptr);",
966
+ } ;
967
+ default :
968
+ return base . GetManagedToMarshalCleanupStatements ( style , variable ) ;
969
+ }
970
+ }
862
971
}
863
972
864
973
class JniReleaseArrayElementsModeTypeInfo : TypeInfo {
@@ -920,6 +1029,7 @@ public override string GetManagedType (HandleStyle style, bool isReturn, bool is
920
1029
case HandleStyle . SafeHandle :
921
1030
case HandleStyle . JIIntPtr :
922
1031
case HandleStyle . JIIntPtrPinvokeWithErrors :
1032
+ case HandleStyle . JIFunctionPtrWithErrors :
923
1033
return type ;
924
1034
case HandleStyle . XAIntPtr :
925
1035
return "IntPtr" ;
@@ -933,6 +1043,7 @@ public override string GetManagedToMarshalExpression (HandleStyle style, string
933
1043
case HandleStyle . SafeHandle :
934
1044
case HandleStyle . JIIntPtr :
935
1045
case HandleStyle . JIIntPtrPinvokeWithErrors :
1046
+ case HandleStyle . JIFunctionPtrWithErrors :
936
1047
return string . Format ( "{0}.ID" , variable ) ;
937
1048
}
938
1049
return variable ;
@@ -947,6 +1058,7 @@ public override string[] VerifyParameter (HandleStyle style, string variable)
947
1058
case HandleStyle . SafeHandle :
948
1059
case HandleStyle . JIIntPtr :
949
1060
case HandleStyle . JIIntPtrPinvokeWithErrors :
1061
+ case HandleStyle . JIFunctionPtrWithErrors :
950
1062
return new [ ] {
951
1063
string . Format ( "if ({0} == null)" , variable ) ,
952
1064
string . Format ( "\t throw new ArgumentNullException (\" {0}\" );" , variableName ) ,
@@ -969,6 +1081,7 @@ public override string[] GetMarshalToManagedStatements (HandleStyle style, strin
969
1081
case HandleStyle . SafeHandle :
970
1082
case HandleStyle . JIIntPtr :
971
1083
case HandleStyle . JIIntPtrPinvokeWithErrors :
1084
+ case HandleStyle . JIFunctionPtrWithErrors :
972
1085
return new [ ] {
973
1086
string . Format ( "if ({0} == IntPtr.Zero)" , variable ) ,
974
1087
string . Format ( "\t return null;" ) ,
@@ -1045,6 +1158,7 @@ public override string GetMarshalType (HandleStyle style, bool isReturn, bool is
1045
1158
return isReturn ? safeType : "JniReferenceSafeHandle" ;
1046
1159
case HandleStyle . JIIntPtr :
1047
1160
case HandleStyle . JIIntPtrPinvokeWithErrors :
1161
+ case HandleStyle . JIFunctionPtrWithErrors :
1048
1162
case HandleStyle . XAIntPtr :
1049
1163
return "jobject" ;
1050
1164
}
@@ -1057,6 +1171,7 @@ public override string GetManagedType (HandleStyle style, bool isReturn, bool is
1057
1171
case HandleStyle . SafeHandle :
1058
1172
case HandleStyle . JIIntPtr :
1059
1173
case HandleStyle . JIIntPtrPinvokeWithErrors :
1174
+ case HandleStyle . JIFunctionPtrWithErrors :
1060
1175
return "JniObjectReference" ;
1061
1176
case HandleStyle . XAIntPtr :
1062
1177
return "IntPtr" ;
@@ -1071,6 +1186,7 @@ public override string GetManagedToMarshalExpression (HandleStyle style, string
1071
1186
return string . Format ( "{0}.SafeHandle" , variable ) ;
1072
1187
case HandleStyle . JIIntPtr :
1073
1188
case HandleStyle . JIIntPtrPinvokeWithErrors :
1189
+ case HandleStyle . JIFunctionPtrWithErrors :
1074
1190
return string . Format ( "{0}.Handle" , variable ) ;
1075
1191
case HandleStyle . XAIntPtr :
1076
1192
return variable ;
@@ -1084,6 +1200,7 @@ public override string[] GetMarshalToManagedStatements (HandleStyle style, strin
1084
1200
case HandleStyle . SafeHandle :
1085
1201
case HandleStyle . JIIntPtr :
1086
1202
case HandleStyle . JIIntPtrPinvokeWithErrors :
1203
+ case HandleStyle . JIFunctionPtrWithErrors :
1087
1204
return new [ ] {
1088
1205
string . Format ( "return new JniObjectReference ({0}, {1});" , variable , refType ) ,
1089
1206
} ;
@@ -1104,6 +1221,7 @@ public override string[] VerifyParameter (HandleStyle style, string variable)
1104
1221
case HandleStyle . SafeHandle :
1105
1222
case HandleStyle . JIIntPtr :
1106
1223
case HandleStyle . JIIntPtrPinvokeWithErrors :
1224
+ case HandleStyle . JIFunctionPtrWithErrors :
1107
1225
return new [ ] {
1108
1226
string . Format ( "if (!{0}.IsValid)" , variable ) ,
1109
1227
string . Format ( "\t throw new ArgumentException (\" Handle must be valid.\" , \" {0}\" );" , variableName ) ,
@@ -1160,13 +1278,50 @@ public JavaVMPointerTypeInfo (string jni)
1160
1278
1161
1279
public override string GetMarshalType ( HandleStyle style , bool isReturn , bool isPinvoke )
1162
1280
{
1281
+ if ( style == HandleStyle . JIFunctionPtrWithErrors && isPinvoke ) {
1282
+ return "IntPtr*" ;
1283
+ }
1163
1284
return "out IntPtr" ;
1164
1285
}
1165
1286
1166
1287
public override string GetManagedType ( HandleStyle style , bool isReturn , bool isPinvoke )
1167
1288
{
1168
1289
return "out IntPtr" ;
1169
1290
}
1291
+
1292
+ public override string GetManagedToMarshalExpression ( HandleStyle style , string variable )
1293
+ {
1294
+ switch ( style ) {
1295
+ case HandleStyle . JIFunctionPtrWithErrors :
1296
+ return $ "_{ variable } _ptr";
1297
+ default :
1298
+ return variable ;
1299
+ }
1300
+ }
1301
+
1302
+ public override string [ ] GetManagedToMarshalPrepareStatements ( HandleStyle style , string variable )
1303
+ {
1304
+ switch ( style ) {
1305
+ case HandleStyle . JIFunctionPtrWithErrors :
1306
+ return new [ ] {
1307
+ $ "IntPtr _{ variable } _ptr = IntPtr.Zero;",
1308
+ } ;
1309
+ default :
1310
+ return base . GetManagedToMarshalPrepareStatements ( style , variable ) ;
1311
+ }
1312
+ }
1313
+
1314
+ public override string [ ] GetManagedToMarshalCleanupStatements ( HandleStyle style , string variable )
1315
+ {
1316
+ switch ( style ) {
1317
+ case HandleStyle . JIFunctionPtrWithErrors :
1318
+ return new [ ] {
1319
+ $ "{ variable } = _{ variable } _ptr;",
1320
+ } ;
1321
+ default :
1322
+ return base . GetManagedToMarshalCleanupStatements ( style , variable ) ;
1323
+ }
1324
+ }
1170
1325
}
1171
1326
1172
1327
class ParamInfo
@@ -1204,6 +1359,7 @@ enum HandleStyle {
1204
1359
JIIntPtr ,
1205
1360
JIIntPtrPinvokeWithErrors ,
1206
1361
XAIntPtr ,
1362
+ JIFunctionPtrWithErrors ,
1207
1363
}
1208
1364
}
1209
1365
0 commit comments