Skip to content

Commit 8074e03

Browse files
committed
[Java.Interop.Export] Begin supporting methods with 14+ params
Context: dotnet/android#4631 Context: https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=3685184&view=logs&j=b1314ebb-4483-559c-0367-730fc62c4440&t=5022c07e-db44-5ce4-1a38-092215b61c50 Context: 70fc4c0 Commit 70fc4c0 broke use of `jnimarshalmethod-gen.exe` within xamarin-android and `Mono.Android.dll`, as it allows methods taking more than 14 parameters to be bound, which results in `jnimarshalmethod-gen.exe` trying to use an `Action<…>` or `Func<…>` that takes more than 16 parameters, which isn't allowed: EXEC : error : jnimarshalmethod-gen: Unable to process assembly '…/xamarin-android/bin/Release/lib/xamarin.android/xbuild-frameworks/MonoAndroid/v10.0/Mono.Android.dll' An incorrect number of type arguments were specified for the declaration of an Action type. Parameter name: typeArgs System.ArgumentException: An incorrect number of type arguments were specified for the declaration of an Action type. Parameter name: typeArgs at System.Linq.Expressions.Expression.GetActionType (System.Type[] typeArgs) at Java.Interop.MarshalMemberBuilder.CreateMarshalToManagedExpression (System.Reflection.MethodInfo method, Java.Interop.JavaCallableAttribute callable, System.Type type) at Java.Interop.MarshalMemberBuilder.CreateMarshalToManagedExpression (System.Reflection.MethodInfo method) at Xamarin.Android.Tools.JniMarshalMethodGenerator.App.CreateMarshalMethodAssembly (System.String path) at Xamarin.Android.Tools.JniMarshalMethodGenerator.App.ProcessAssemblies (System.Collections.Generic.List`1[T] assemblies) Update `jnimarshalmethod-gen.exe` so that it *skips* methods which take more than 14 parameters. This is to unblock xamarin-android integrations. (Hopefully this in itself will be enough for xamarin-android to build.) Next, *begin* plumbing support for this scenario. To remove the workaround and get things fully working (failing), rebuild `jnimarshalmethod-gen.exe` with: msbuild /restore tools/jnimarshalmethod-gen/Xamarin.Android.Tools.JniMarshalMethodGenerator.csproj /p:_AllTheArguments=True Also update `jnimarshalmethod-gen.exe` so that it *optionally* uses `Mono.Linq.Expressions`, for additional debugging output: msbuild /restore tools/jnimarshalmethod-gen/Xamarin.Android.Tools.JniMarshalMethodGenerator.csproj /p:_DumpRegisterNativeMembers=True (Use `/p:_AllTheArguments=True /p:_DumpRegisterNativeMembers=True` for both!) Add a method to `ExportTest.cs` / `ExportType.java` which takes more than 14 parameters, and update `MarshalMemberBuilder` so that it can generate the appropriate JNI Marshal Method for such a method. (This should help avoid the need for xamarin-android integrations to see what's broken.) The complexity of supporting more than 14 parameters doesn't like in `MarshalMemberBuilder`, per-se; `Java.Interop.Export-Tests.dll` runs just fine when just using `Expression.Lambda(body, bodyParams)`. Things get much more complicated when `jnimarshalmethod-gen.exe` enters the picture, and interacts with `MarshalMemberBuilder`. `jnimarshalmethod-gen.exe` *requires* an "appropriate" delegate type. Update `MarshalMemberBuilder` to "know about" the `_JniMarshal*` delegates added in cbb50af, and attempt to use them from the assembly that is being processed, if they exist. This got further, resulting in an error that `_JniMarshal_PPZBCSIJFDLLLLLDFJ_Z` can't be used as a constant (?!). Address *that* error by updating `App.cs` so that it emits a `Type.GetType("_JniMarshal_PPZBCSIJFDLLLLLDFJ_Z", true)`. This allows `jnimarshalmethod-gen.exe` to execute successfully. Then we try *running* it, and it fails: $ make run-test-jnimarshal … EXEC : 1) error : Java.InteropTests.MarshalMemberBuilderTest.AddExportMethods […/Java.Interop/build-tools/scripts/RunNUnitTests.targets] Java.Interop.JavaException : com.xamarin.interop.export.ExportType.staticAction()V at Java.Interop.JniEnvironment+StaticMethods.CallStaticVoidMethod (Java.Interop.JniObjectReference type, Java.Interop.JniMethodInfo method) at Java.InteropTests.MarshalMemberBuilderTest.AddExportMethods () at (wrapper managed-to-native) System.Reflection.RuntimeMethodInfo.InternalInvoke(System.Reflection.RuntimeMethodInfo,object,object[],System.Exception&) at System.Reflection.RuntimeMethodInfo.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) --- End of managed Java.Interop.JavaException stack trace --- java.lang.UnsatisfiedLinkError: com.xamarin.interop.export.ExportType.staticAction()V at com.xamarin.interop.export.ExportType.staticAction(Native Method) at com.xamarin.interop.export.ExportType.testStaticMethods(ExportType.java:26)> Add more printfs, and we get the problem: System.InvalidProgramException: Invalid IL code in Java.InteropTests.ExportTest/__<$>_jni_marshal_methods:__RegisterNativeMembers (Java.Interop.JniNativeMethodRegistrationArguments): IL_0176: ldloc.0 At this point things don't make sense to me. The `__RegisterNativeMembers()` method is: ## Dumping contents of `Java.InteropTests.ExportTest::__RegisterNativeMembers`: void (JniNativeMethodRegistrationArguments args) { Type targetType; targetType = Type.GetType("Java.InteropTests.ExportTest"); args.AddRegistrations(new JniNativeMethodRegistration[] { new JniNativeMethodRegistration("funcIJavaObject", "()Ljava/lang/Object;", Delegate.CreateDelegate(System.Func`3[System.IntPtr,System.IntPtr,System.IntPtr], targetType, "FuncIJavaObject")), new JniNativeMethodRegistration("funcInt64", "()J", Delegate.CreateDelegate(System.Func`3[System.IntPtr,System.IntPtr,System.Int64], targetType, "FuncInt64")), new JniNativeMethodRegistration("action", "()V", Delegate.CreateDelegate(System.Action`2[System.IntPtr,System.IntPtr], targetType, "InstanceAction")), new JniNativeMethodRegistration("actionIJavaObject", "(Ljava/lang/Object;)V", Delegate.CreateDelegate(System.Action`3[System.IntPtr,System.IntPtr,System.IntPtr], targetType, "InstanceActionIJavaObject")), new JniNativeMethodRegistration("staticAction", "()V", Delegate.CreateDelegate(System.Action`2[System.IntPtr,System.IntPtr], targetType, "StaticAction")), new JniNativeMethodRegistration("staticActionFloat", "(F)V", Delegate.CreateDelegate(System.Action`3[System.IntPtr,System.IntPtr,System.Single], targetType, "StaticActionFloat")), new JniNativeMethodRegistration("staticActionIJavaObject", "(Ljava/lang/Object;)V", Delegate.CreateDelegate(System.Action`3[System.IntPtr,System.IntPtr,System.IntPtr], targetType, "StaticActionIJavaObject")), new JniNativeMethodRegistration("staticActionInt", "(I)V", Delegate.CreateDelegate(System.Action`3[System.IntPtr,System.IntPtr,System.Int32], targetType, "StaticActionInt")), new JniNativeMethodRegistration("staticActionInt32String", "(ILjava/lang/String;)V", Delegate.CreateDelegate(System.Action`4[System.IntPtr,System.IntPtr,System.Int32,System.IntPtr], targetType, "StaticActionInt32String")), new JniNativeMethodRegistration("staticFuncMyLegacyColorMyColor_MyColor", "(II)I", Delegate.CreateDelegate(System.Func`5[System.IntPtr,System.IntPtr,System.Int32,System.Int32,System.Int32], targetType, "StaticFuncMyLegacyColorMyColor_MyColor")), new JniNativeMethodRegistration("staticFuncThisMethodTakesLotsOfParameters", "(ZBCSIJFDLjava/lang/Object;Ljava/lang/String;Ljava/util/ArrayList;Ljava/lang/String;Ljava/lang/Object;DFJ)Z", Delegate.CreateDelegate((Type)Type.GetType("_JniMarshal_PPZBCSIJFDLLLLLDFJ_Z", true), targetType, "StaticFuncThisMethodTakesLotsOfParameters")) }); } The offending IL fragment: … IL_0161: ldstr "staticFuncThisMethodTakesLotsOfParameters" IL_0166: ldstr "(ZBCSIJFDLjava/lang/Object;Ljava/lang/String;Ljava/util/ArrayList;Ljava/lang/String;Ljava/lang/Object;DFJ)Z" IL_016b: ldstr "_JniMarshal_PPZBCSIJFDLLLLLDFJ_Z" IL_0170: ldc.i4.1 IL_0171: call [mscorlib]System.Type [mscorlib]System.Type::GetType(string, bool) IL_0176: ldloc.0 IL_0177: ldstr "StaticFuncThisMethodTakesLotsOfParameters" IL_017c: call [mscorlib]System.Delegate [mscorlib]System.Delegate::CreateDelegate([mscorlib]System.Type, [mscorlib]System.Type, string) IL_0181: newobj instance void [Java.Interop]Java.Interop.JniNativeMethodRegistration::.ctor(string, string, [mscorlib]System.Delegate) I don't understand where the `ldloc.0` is coming from, or why it's there. Punting a complete fix for now. To repro the crash: $ rm -Rf bin/TestDebug $ msbuild $ msbuild /restore tools/jnimarshalmethod-gen/Xamarin.Android.Tools.JniMarshalMethodGenerator.csproj /p:_AllTheArguments=True /p:_DumpRegisterNativeMembers=True $ make run-test-jnimarshal
1 parent 9876e31 commit 8074e03

File tree

7 files changed

+230
-23
lines changed

7 files changed

+230
-23
lines changed

src/Java.Interop.Export/Java.Interop.Export.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
<Project Sdk="Microsoft.NET.Sdk">
33
<PropertyGroup>
44
<TargetFramework>netstandard2.0</TargetFramework>
5+
<LangVersion>8.0</LangVersion>
56
<ProjectGuid>{B501D075-6183-4E1D-92C9-F7B5002475B1}</ProjectGuid>
67
<SignAssembly>true</SignAssembly>
78
<AssemblyOriginatorKeyFile>..\..\product.snk</AssemblyOriginatorKeyFile>

src/Java.Interop.Export/Java.Interop/MarshalMemberBuilder.cs

Lines changed: 56 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -229,15 +229,64 @@ public LambdaExpression CreateMarshalToManagedExpression (MethodInfo method, Jav
229229
}
230230
foreach (var p in marshalParameters)
231231
funcTypeParams.Add (p.Type);
232-
if (ret != null)
233-
funcTypeParams.Add (ret.Type);
234-
var marshalerType = ret == null
235-
? Expression.GetActionType (funcTypeParams.ToArray ())
236-
: Expression.GetFuncType (funcTypeParams.ToArray ());
232+
var marshalerType = GetMarshalerType (ret?.Type, funcTypeParams, method.DeclaringType);
237233

238234
bodyParams.AddRange (marshalParameters);
239235
var body = Expression.Block (envpVars, envpBody);
240-
return Expression.Lambda (marshalerType, body, bodyParams);
236+
237+
return marshalerType == null
238+
? Expression.Lambda (body, bodyParams)
239+
: Expression.Lambda (marshalerType, body, bodyParams);
240+
}
241+
242+
static Type GetMarshalerType (Type returnType, List<Type> funcTypeParams, Type declaringType)
243+
{
244+
// `mscorlib.dll` & `System.Core.dll` only provide Action<…>/Func<…> types for up to 16 parameters
245+
if (funcTypeParams.Count <= 16) {
246+
if (returnType != null)
247+
funcTypeParams.Add (returnType);
248+
return returnType == null
249+
? Expression.GetActionType (funcTypeParams.ToArray ())
250+
: Expression.GetFuncType (funcTypeParams.ToArray ());
251+
}
252+
253+
// Too many parameters; does a `_JniMarshal_*` type exist in the type's declaring assembly?
254+
funcTypeParams.RemoveRange (0, 2);
255+
var marshalDelegateName = new StringBuilder ();
256+
marshalDelegateName.Append ("_JniMarshal_PP");
257+
foreach (var paramType in funcTypeParams) {
258+
marshalDelegateName.Append (GetJniMarshalDelegateParameterIdentifier (paramType));
259+
}
260+
marshalDelegateName.Append ("_");
261+
if (returnType == null) {
262+
marshalDelegateName.Append ("V");
263+
} else {
264+
marshalDelegateName.Append (GetJniMarshalDelegateParameterIdentifier (returnType));
265+
}
266+
267+
Type marshalDelegateType = declaringType.Assembly.GetType (marshalDelegateName.ToString (), throwOnError: false);
268+
269+
// Punt?; System.Linq.Expressions will automagically produce the needed delegate type.
270+
// Unfortunately, this won't work with jnimarshalmethod-gen.exe.
271+
return marshalDelegateType;
272+
}
273+
274+
static char GetJniMarshalDelegateParameterIdentifier (Type type)
275+
{
276+
if (type == typeof (bool)) return 'Z';
277+
if (type == typeof (byte)) return 'B';
278+
if (type == typeof (sbyte)) return 'B';
279+
if (type == typeof (char)) return 'C';
280+
if (type == typeof (short)) return 'S';
281+
if (type == typeof (ushort)) return 's';
282+
if (type == typeof (int)) return 'I';
283+
if (type == typeof (uint)) return 'i';
284+
if (type == typeof (long)) return 'J';
285+
if (type == typeof (ulong)) return 'j';
286+
if (type == typeof (float)) return 'F';
287+
if (type == typeof (double)) return 'D';
288+
if (type == typeof (void)) return 'V';
289+
return 'L';
241290
}
242291

243292
void CheckMarshalTypesMatch (MethodInfo method, string signature, ParameterInfo[] methodParameters)
@@ -258,7 +307,7 @@ void CheckMarshalTypesMatch (MethodInfo method, string signature, ParameterInfo[
258307
var jni = vm.MarshalType;
259308
if (mptypes [i] != jni)
260309
throw new ArgumentException (
261-
string.Format ("JNI parameter type mismatch. Type '{0}' != '{1}.", jni, mptypes [i]),
310+
$"JNI parameter type mismatch. Type `{jni}` != `{mptypes [i]}` at index {i} in `{signature}`.",
262311
"signature");
263312
}
264313

tests/Java.Interop.Export-Tests/Java.Interop/ExportTest.cs

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,28 @@
66
using Java.Interop;
77
using Java.Interop.Expressions;
88

9+
// For use by `jnimarshalmethod-gen.exe` & `make run-test-jnimarshal`
10+
delegate bool _JniMarshal_PPZBCSIJFDLLLLLDFJ_Z (
11+
IntPtr jnienv,
12+
IntPtr klass,
13+
bool a,
14+
sbyte b,
15+
char c,
16+
short d,
17+
int e,
18+
long f,
19+
float g,
20+
double h,
21+
IntPtr i, // java.lang.Object
22+
IntPtr j, // java.lang.String
23+
IntPtr k, // java.util.ArrayList<String>
24+
IntPtr l, // java.lang.String
25+
IntPtr m, // java.lang.Object
26+
double n,
27+
float o,
28+
long p
29+
);
30+
931
namespace Java.InteropTests
1032
{
1133
[JniTypeSignature ("com/xamarin/interop/export/ExportType")]
@@ -83,6 +105,60 @@ public static void StaticActionInt (int i)
83105
public static void StaticActionFloat (float f)
84106
{
85107
}
108+
109+
[JavaCallable ("staticFuncThisMethodTakesLotsOfParameters", Signature="(ZBCSIJFDLjava/lang/Object;Ljava/lang/String;Ljava/util/ArrayList;Ljava/lang/String;Ljava/lang/Object;DFJ)Z")]
110+
public static bool StaticFuncThisMethodTakesLotsOfParameters (
111+
bool a,
112+
sbyte b,
113+
char c,
114+
short d,
115+
int e,
116+
long f,
117+
float g,
118+
double h,
119+
IntPtr i, // java.lang.Object
120+
IntPtr j, // java.lang.String
121+
IntPtr k, // java.util.ArrayList<String>
122+
IntPtr l, // java.lang.String
123+
IntPtr m, // java.lang.Object
124+
double n,
125+
float o,
126+
long p)
127+
{
128+
if (a != false)
129+
return false;
130+
if (b != (byte) 0xb)
131+
return false;
132+
if (c != 'c')
133+
return false;
134+
if (d != (short) 0xd)
135+
return false;
136+
if (e != 0xe)
137+
return false;
138+
if (f != 0xf)
139+
return false;
140+
if (g != 1.0f)
141+
return false;
142+
if (h != 2.0)
143+
return false;
144+
if (i == IntPtr.Zero)
145+
return false;
146+
if (j == IntPtr.Zero)
147+
return false;
148+
if (k == IntPtr.Zero)
149+
return false;
150+
if (l == IntPtr.Zero)
151+
return false;
152+
if (m == IntPtr.Zero)
153+
return false;
154+
if (n != 3.0)
155+
return false;
156+
if (o != 4.0f)
157+
return false;
158+
if (p != 0x70)
159+
return false;
160+
return true;
161+
}
86162
}
87163

88164
[JniValueMarshaler (typeof (MyColorValueMarshaler))]

tests/Java.Interop.Export-Tests/Java.Interop/MarshalMemberBuilderTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public void AddExportMethods ()
2222
var methods = CreateBuilder ()
2323
.GetExportedMemberRegistrations (typeof (ExportTest))
2424
.ToList ();
25-
Assert.AreEqual (10, methods.Count);
25+
Assert.AreEqual (11, methods.Count);
2626

2727
Assert.AreEqual ("action", methods [0].Name);
2828
Assert.AreEqual ("()V", methods [0].Signature);

tests/Java.Interop.Export-Tests/java/com/xamarin/interop/export/ExportType.java

Lines changed: 55 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,21 +30,62 @@ public static void testStaticMethods () {
3030
public static native void staticActionInt32String (int i, String s);
3131
public static native int staticFuncMyLegacyColorMyColor_MyColor (int color1, int color2);
3232

33-
public void testMethods () {
34-
action ();
35-
36-
actionIJavaObject (this);
37-
38-
long j = funcInt64 ();
39-
if (j != 42)
40-
throw new Error ("funcInt64() should return 42!");
33+
public static native boolean staticFuncThisMethodTakesLotsOfParameters (
34+
boolean a,
35+
byte b,
36+
char c,
37+
short d,
38+
int e,
39+
long f,
40+
float g,
41+
double h,
42+
Object i,
43+
String j,
44+
ArrayList<String> k,
45+
String l,
46+
Object m,
47+
double n,
48+
float o,
49+
long p);
4150

42-
Object o = funcIJavaObject ();
43-
if (o != this)
44-
throw new Error ("funcIJavaObject() should return `this`!");
45-
46-
staticActionInt (1);
47-
staticActionFloat (2.0f);
51+
public void testMethods () {
52+
action ();
53+
54+
actionIJavaObject (this);
55+
56+
long j = funcInt64 ();
57+
if (j != 42)
58+
throw new Error ("funcInt64() should return 42!");
59+
60+
Object o = funcIJavaObject ();
61+
if (o != this)
62+
throw new Error ("funcIJavaObject() should return `this`!");
63+
64+
staticActionInt (1);
65+
staticActionFloat (2.0f);
66+
67+
/*
68+
boolean r = staticFuncThisMethodTakesLotsOfParameters (
69+
false,
70+
(byte) 0xb,
71+
'c',
72+
(short) 0xd,
73+
0xe,
74+
0xf,
75+
1.0f,
76+
2.0,
77+
new Object (),
78+
"j",
79+
new ArrayList<String>(),
80+
"l",
81+
new Object (),
82+
3.0,
83+
4.0f,
84+
0x70
85+
);
86+
if (r != true)
87+
throw new Error ("staticFuncThisMethodTakesLotsOfParameters should return true!");
88+
*/
4889
}
4990

5091
public native void action ();

tools/jnimarshalmethod-gen/App.cs

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@
1313
using Mono.Collections.Generic;
1414
using Java.Interop.Tools.Cecil;
1515

16+
#if _DUMP_REGISTER_NATIVE_MEMBERS
17+
using Mono.Linq.Expressions;
18+
#endif // _DUMP_REGISTER_NATIVE_MEMBERS
19+
1620
namespace Xamarin.Android.Tools.JniMarshalMethodGenerator {
1721

1822
class App : MarshalByRefObject
@@ -393,6 +397,13 @@ void CreateMarshalMethodAssembly (string path)
393397
continue;
394398
}
395399

400+
#if !_ALL_THE_ARGUMENTS
401+
if (method.GetParameters ().Length > 14) {
402+
Warning ($"Methods taking more than 14 parameters is not supported.");
403+
continue;
404+
}
405+
#endif // !_ALL_THE_ARGUMENTS
406+
396407
if (dt == null)
397408
dt = GetTypeBuilder (dm, type);
398409

@@ -467,7 +478,20 @@ void CreateMarshalMethodAssembly (string path)
467478

468479
static Expression CreateRegistration (string method, string signature, LambdaExpression lambda, ParameterExpression targetType, string methodName)
469480
{
470-
var d = Expression.Call (Delegate_CreateDelegate, Expression.Constant (lambda.Type, typeof (Type)), targetType, Expression.Constant (methodName));
481+
Expression registrationDelegateType = null;
482+
if (lambda.Type.Assembly == typeof (object).Assembly ||
483+
lambda.Type.Assembly == typeof (System.Linq.Enumerable).Assembly) {
484+
registrationDelegateType = Expression.Constant (lambda.Type, typeof (Type));
485+
}
486+
else {
487+
Func<string, bool, Type> getType = Type.GetType;
488+
registrationDelegateType = Expression.Call (getType.GetMethodInfo (),
489+
Expression.Constant (lambda.Type.FullName, typeof (string)),
490+
Expression.Constant (true, typeof (bool)));
491+
registrationDelegateType = Expression.Convert (registrationDelegateType, typeof (Type));
492+
}
493+
494+
var d = Expression.Call (Delegate_CreateDelegate, registrationDelegateType, targetType, Expression.Constant (methodName));
471495
return Expression.New (JniNativeMethodRegistration_ctor,
472496
Expression.Constant (method),
473497
Expression.Constant (signature),
@@ -488,6 +512,10 @@ static void AddRegisterNativeMembers (TypeBuilder dt, ParameterExpression target
488512
var rb = dt.DefineMethod ("__RegisterNativeMembers",
489513
System.Reflection.MethodAttributes.Public | System.Reflection.MethodAttributes.Static);
490514
rb.SetCustomAttribute (new CustomAttributeBuilder (typeof (JniAddNativeMethodRegistrationAttribute).GetConstructor (Type.EmptyTypes), new object[0]));
515+
#if _DUMP_REGISTER_NATIVE_MEMBERS
516+
Console.WriteLine ($"## Dumping contents of `{dt.FullName}::__RegisterNativeMembers`: ");
517+
Console.WriteLine (lambda.ToCSharpCode ());
518+
#endif // _DUMP_REGISTER_NATIVE_MEMBERS
491519
lambda.CompileToMethod (rb);
492520
}
493521

tools/jnimarshalmethod-gen/Xamarin.Android.Tools.JniMarshalMethodGenerator.csproj

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,23 @@
1212
<PropertyGroup>
1313
<OutputPath>$(UtilityOutputFullPath)</OutputPath>
1414
</PropertyGroup>
15+
16+
<PropertyGroup Condition=" '$(_DumpRegisterNativeMembers)' == 'True' ">
17+
<DefineConstants>_DUMP_REGISTER_NATIVE_MEMBERS;$(DefineConstants)</DefineConstants>
18+
</PropertyGroup>
19+
20+
<PropertyGroup Condition=" '$(_AllTheArguments)' == 'True' ">
21+
<DefineConstants>_ALL_THE_ARGUMENTS;$(DefineConstants)</DefineConstants>
22+
</PropertyGroup>
1523

1624
<ItemGroup>
1725
<PackageReference Include="Mono.Options" Version="5.3.0.1" />
1826
</ItemGroup>
1927

28+
<ItemGroup Condition=" '$(_DumpRegisterNativeMembers)' == 'True' ">
29+
<PackageReference Include="Mono.Linq.Expressions" Version="2.0.0" />
30+
</ItemGroup>
31+
2032
<ItemGroup>
2133
<ProjectReference Include="..\..\src\Java.Interop.Export\Java.Interop.Export.csproj" />
2234
<ProjectReference Include="..\..\src\Java.Interop\Java.Interop.csproj" />

0 commit comments

Comments
 (0)