Commit 77a6bf8
committed
[Java.Interop] Replace JniMarshalInfo with JniValueMarshaler.
Context: dotnet#2
Context: dotnet#8
From Issue dotnet#8:
> I don't like JniMarshalInfo; it's too convoluted, makes the
> simple cases hard.
What do we mean by "hard"? We mean that it's use is error prone,
because what you need to do depends on the values of the
JniMarshalInfo members, which is best characterized by what
JniArgumentMarshalInfo had to do to create a JNI Local refererence:
JniObjectReference lref;
var marshaler = JniRuntime.CurrentRuntime.ValueManager.GetJniMarshalInfoForType (type);
if (info.CreateMarshalCollection != null) {
var obj = info.CreateMarshalCollection (value);
lref = obj.PeerReference;
} else if (info.CreateLocalRef != null) {
lref = info.CreateLocalRef (value);
} else
throw new NotSupportedException ("Don't know how to get a JNI Local Reference!");
// can now use `lref`...
Need to pass as a method argument? Similar-yet-different. Then
there's the cleanup code!
The eventual intention is for tools/jnimarshalmethod-gen to
post-process assemblies and generate Java > Managed marshal methods
for all resolvable methods, and do this "dynamically" based on the
actual types involved. This will allow "fixing" binding assemblies
when involved types change, because binding assemblies won't be as
"static" as they are in Xamarin.Android. (Which is why Issue dotnet#8
mentions using Expressions for the marshaling.)
However, before we can get there we first need a rational marshaling
abstrasction, something that is "pluggable" and readily extensible, so
taht we can e.g. have a custom attribute to control which marshaler to
use on types, parameters, and method return types. JniMarshalInfo
wasn't that abstraction, and couldn't *be* that abstraction.
To replace JniMarshalInfo, introduce JniValueMarshaler and
JniValueMarshler<T>:
public abstract partial class JniValueMarshaler {
public abstract object CreateValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType = null);
public virtual JniValueMarshalerState CreateArgumentState (object value, ParameterAttributes synchronize = 0);
public abstract JniValueMarshalerState CreateObjectReferenceArgumentState (object value, ParameterAttributes synchronize = 0);
public abstract void DestroyArgumentState (object value, ref JniValueMarshalerState state, ParameterAttributes synchronize = 0);
}
public abstract partial class JniValueMarshaler<T> : JniValueMarshaler {
public abstract T CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType = null);
public virtual JniValueMarshalerState CreateGenericArgumentState (T value, ParameterAttributes synchronize = 0);
public abstract JniValueMarshalerState CreateGenericObjectReferenceArgumentState (T value, ParameterAttributes synchronize = 0);
public abstract void DestroyGenericArgumentState (T value, ref JniValueMarshalerState state, ParameterAttributes synchronize = 0);
public override object CreateValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType = null);
public override JniValueMarshalerState CreateArgumentState (object value, ParameterAttributes synchronize = 0);
public override JniValueMarshalerState CreateObjectReferenceArgumentState (object value, ParameterAttributes synchronize = 0);
public override void DestroyArgumentState (object value, ref JniValueMarshalerState state, ParameterAttributes synchronize = 0);
}
The intention is that a custom marshaler can be introduced by
inheriting from JniValueMarshaler<T> and overriding three methods.
This also provides a reasonable abstraction, e.g. to create a
JNI Local Reference:
var state = marshaler.CreateGenericObjectReferenceArgumentState (value);
// state.ReferenceValue contains a JNI Object Reference
// use, then cleanup:
marshaler.DestroyGenericArgumentState (value, ref state);
The methods are as follows:
* CreateValue, CreateGenericValue:
Java > Managed marshaler.
Given a JniObjectReference, marshal the value to a type compatible
with specified targetType, which should be either null or a class
assignment compatible to T.
The other methods use a JniValueMarshalerState type:
public partial struct JniValueMarshalerState {
public JniArgumentValue JniArgumentValue {get;}
public JniObjectReference ReferenceValue {get;}
public IJavaPeerable PeerableValue {get;}
}
The remaining methods of import are:
* CreateArgumentState(), CreateGenericArgumentState():
Managed > Java marshaler.
Used when the intention is to use
JniValueMarshalerState.JniArgumentValue, which in turn is for use
with JniEnvironment.*Methods.Call*Method().
* CreateObjectReferenceArgumentState(),
CreateGenericObjectReferenceArgumentState():
Managed > Java marshaler.
Used when the intention is to use
JniValueMarshalerState.ReferenceValue.
* DestroyArgumentState(), DestroyGenericArgumentState(): Generic
resource cleanup mechanism for use with Create*ArgumentState().
The primary difference between Create*ArgumentState() and
Create*ObjectReferenceArgumentState() is with builtin value types,
e.g. `int`. Create*ArgumentState() will *only* provide a
JniArgumentValue, while JniValueMarshalerState.ReferenceValue will be
null. Create*ObjectReferenceArgumentState(), meanwhile, will "box" the
value type, providing a valid JniValueMarshalerState.ReferenceValue.
For all other types, these methods are identical.
JniValueMarshaler and JniValueMarshalerState together combine to
replace JniMarshalInfo and JniArgumentMarshalInfo, the latter of which
(1) wasn't public, and (2) was "duplicated" between the generic
marshalers and Java.Interop.Dynamic. JniValueMarshaler thus allows
cleaning up this duplication.
Along with the new JniValueMarshaler abstraction, we provide
implementations for all builtin types, Nullable<T> for builtin types
(which always box), arrays of the builtin types, JavaObjectArray<T>,
IJavaPeerable, and `object`.
The `object` marshaler supersedes the previous
JniMarshal.GetValue<T>() semantics, using JavaProxyObject as needed.
One thing to note is the ParameterAttributes parameters. This value
is intended to correspond with
System.Reflection.ParameterInfo.Attributes. jnimarshalmethod-gen can
thus use the actual MethodInfo + ParameterInfo to encode parameter
marshaling direction. For most types this won't be useful; this is
largely intended for *arrays*, e.g. we could have an `[In] int[]`
parameter which thus avoids the "copy out" behavior Xamarin.Android
currently performs, thus avoiding an extra JNI transition. Or
vice-versa, have an `[Out] int[]` parameter, which avoids a JNI
transition to copy the managed `int[]` to the Java `int[]`, replacing
it with the copy-out transition.
Partially addressing Issue dotnet#2, this also introduces
JniRuntime.JniValueManager.GetValue() and GetValue<T>() methods.
GetObject() is not yet replaced, but will be in a future commit.
Actual implementation will be done alongside introduction of
CreateValue<T>() and cleaning up JniValueMarshaler.Create*Value()
methods to always create values when able, simplifying the logic if
JniValueMarshaler implementations.1 parent 15fbb57 commit 77a6bf8
File tree
23 files changed
+10905
-6938
lines changed- src
- Java.Interop.Dynamic/Java.Interop.Dynamic
- Java.Interop
- Java.Interop
- Tests
- Java.Interop
23 files changed
+10905
-6938
lines changedLines changed: 0 additions & 36 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
144 | 144 | | |
145 | 145 | | |
146 | 146 | | |
147 | | - | |
148 | | - | |
149 | | - | |
150 | | - | |
151 | | - | |
152 | | - | |
153 | | - | |
154 | | - | |
155 | | - | |
156 | | - | |
157 | | - | |
158 | | - | |
159 | | - | |
160 | | - | |
161 | | - | |
162 | | - | |
163 | | - | |
164 | | - | |
165 | | - | |
166 | | - | |
167 | | - | |
168 | | - | |
169 | | - | |
170 | | - | |
171 | | - | |
172 | | - | |
173 | | - | |
174 | | - | |
175 | | - | |
176 | | - | |
177 | | - | |
178 | | - | |
179 | | - | |
180 | | - | |
181 | | - | |
182 | | - | |
183 | 147 | | |
184 | 148 | | |
Lines changed: 13 additions & 7 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
291 | 291 | | |
292 | 292 | | |
293 | 293 | | |
294 | | - | |
| 294 | + | |
| 295 | + | |
295 | 296 | | |
296 | 297 | | |
297 | 298 | | |
| |||
300 | 301 | | |
301 | 302 | | |
302 | 303 | | |
303 | | - | |
304 | | - | |
305 | | - | |
306 | | - | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
307 | 313 | | |
308 | 314 | | |
309 | 315 | | |
310 | 316 | | |
311 | | - | |
312 | | - | |
| 317 | + | |
| 318 | + | |
313 | 319 | | |
314 | 320 | | |
315 | 321 | | |
| |||
Lines changed: 16 additions & 6 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
137 | 137 | | |
138 | 138 | | |
139 | 139 | | |
140 | | - | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
141 | 146 | | |
142 | | - | |
| 147 | + | |
143 | 148 | | |
144 | | - | |
| 149 | + | |
145 | 150 | | |
146 | 151 | | |
147 | 152 | | |
| |||
163 | 168 | | |
164 | 169 | | |
165 | 170 | | |
166 | | - | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
167 | 177 | | |
168 | | - | |
| 178 | + | |
169 | 179 | | |
170 | | - | |
| 180 | + | |
171 | 181 | | |
172 | 182 | | |
173 | 183 | | |
| |||
Lines changed: 6 additions & 4 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
52 | 52 | | |
53 | 53 | | |
54 | 54 | | |
55 | | - | |
56 | | - | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
57 | 60 | | |
| 61 | + | |
58 | 62 | | |
59 | | - | |
60 | | - | |
61 | 63 | | |
62 | 64 | | |
63 | 65 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
119 | 119 | | |
120 | 120 | | |
121 | 121 | | |
122 | | - | |
123 | 122 | | |
124 | 123 | | |
125 | 124 | | |
126 | 125 | | |
127 | 126 | | |
128 | 127 | | |
| 128 | + | |
129 | 129 | | |
| 130 | + | |
130 | 131 | | |
131 | 132 | | |
132 | 133 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3 | 3 | | |
4 | 4 | | |
5 | 5 | | |
| 6 | + | |
6 | 7 | | |
7 | 8 | | |
8 | 9 | | |
| |||
102 | 103 | | |
103 | 104 | | |
104 | 105 | | |
105 | | - | |
| 106 | + | |
106 | 107 | | |
107 | 108 | | |
108 | 109 | | |
| |||
125 | 126 | | |
126 | 127 | | |
127 | 128 | | |
128 | | - | |
129 | | - | |
130 | | - | |
131 | | - | |
132 | | - | |
133 | | - | |
134 | | - | |
135 | | - | |
136 | | - | |
137 | | - | |
138 | | - | |
139 | | - | |
140 | | - | |
141 | | - | |
142 | | - | |
143 | | - | |
| 129 | + | |
144 | 130 | | |
145 | 131 | | |
146 | 132 | | |
| |||
153 | 139 | | |
154 | 140 | | |
155 | 141 | | |
156 | | - | |
| 142 | + | |
157 | 143 | | |
158 | 144 | | |
159 | 145 | | |
160 | | - | |
| 146 | + | |
161 | 147 | | |
162 | | - | |
163 | | - | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
164 | 151 | | |
165 | 152 | | |
166 | 153 | | |
167 | | - | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
168 | 158 | | |
169 | 159 | | |
170 | | - | |
| 160 | + | |
171 | 161 | | |
172 | 162 | | |
173 | | - | |
| 163 | + | |
174 | 164 | | |
175 | 165 | | |
176 | 166 | | |
177 | | - | |
178 | | - | |
179 | | - | |
180 | | - | |
181 | | - | |
182 | | - | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
183 | 177 | | |
184 | 178 | | |
185 | 179 | | |
186 | 180 | | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
187 | 193 | | |
188 | 194 | | |
189 | 195 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
| 3 | + | |
3 | 4 | | |
4 | 5 | | |
5 | 6 | | |
| |||
59 | 60 | | |
60 | 61 | | |
61 | 62 | | |
62 | | - | |
| 63 | + | |
63 | 64 | | |
64 | 65 | | |
65 | 66 | | |
66 | 67 | | |
67 | | - | |
68 | | - | |
69 | | - | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
70 | 72 | | |
71 | 73 | | |
72 | 74 | | |
| |||
80 | 82 | | |
81 | 83 | | |
82 | 84 | | |
83 | | - | |
| 85 | + | |
| 86 | + | |
84 | 87 | | |
85 | | - | |
| 88 | + | |
86 | 89 | | |
87 | | - | |
| 90 | + | |
88 | 91 | | |
89 | 92 | | |
90 | 93 | | |
| |||
132 | 135 | | |
133 | 136 | | |
134 | 137 | | |
135 | | - | |
136 | | - | |
137 | | - | |
138 | | - | |
139 | | - | |
140 | | - | |
| 138 | + | |
141 | 139 | | |
142 | | - | |
143 | | - | |
144 | | - | |
145 | | - | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
146 | 146 | | |
147 | | - | |
148 | | - | |
149 | | - | |
150 | | - | |
151 | | - | |
152 | | - | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
153 | 157 | | |
154 | | - | |
155 | | - | |
156 | | - | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
157 | 162 | | |
158 | 163 | | |
159 | 164 | | |
| |||
0 commit comments