Open
Description
Background and motivation
For interop with JVM based languages, an interaction model must be made to facilitate lifetime managements through GC coordination. This support is primary for Android for .NET, but there is no technical limitation to this support being enabled for non-Android scenarios.
See #114184 and https://github.com/BrzVlad/runtime/tree/feature-clr-gcbridge
API Proposal
namespace System.Runtime.InteropServices.Java;
[SupportedOSPlatform("android")]
public struct ComponentCrossReference
{
public nint SourceGroupIndex;
public nint DestinationGroupIndex;
}
[SupportedOSPlatform("android")]
public unsafe struct StronglyConnectedComponent
{
public nint Count;
public System.IntPtr* Contexts;
}
[SupportedOSPlatform("android")]
public unsafe struct MarkCrossReferences
{
public nint ComponentsLen;
public StronglyConnectedComponent* Components;
public nint CrossReferencesLen;
public ComponentCrossReference* CrossReferences;
}
[SupportedOSPlatform("android")]
partial static class JavaMarshal
{
public static unsafe void Initialize(delegate* unmanaged<MarkCrossReferences*, void> markCrossReferences);
public static GCHandle CreateCrossReferenceHandle(object obj, IntPtr context);
public static IntPtr GetContext(GCHandle obj);
public static unsafe void FinishCrossReferenceProcessing(
MarkCrossReferences* crossReferences,
Span<GCHandle> unreachableObjectHandles);
}
API Usage
// Early in application start-up, a callback is provided.
JavaMarshal.Initialize(...);
object javaProxy = ...
var userContext = (IntPtr)NativeMemory.Alloc(...);
// Store data in context.
GCHandle handle = JavaMarshal.CreateCrossReferenceHandle(javaProxy, userContext);
// Store handle in a map from JNI handle to Object for fast retrieval
// Get GCHandle associated with JNI handle
GCHandle handle = ...
var userContext = JavaMarshal.GetContext(handle);
// Extract data from context.
// Free memory passed to callback registered in JavaMarshal.Initialize().
MarkCrossReferences* markRefsMem = ...;
// Collect all GCHandles marked as "unreachable"
Span<GCHandle> unreachableObjects = ...;
JavaMarshal.FinishCrossReferenceProcessing(markRefsMem, unreachableObjects);
Case example can be found at #114184
Alternative Designs
Place under System.Runtime.InteropServices.GCBridge
Do not limit to SupportedOSPlatform("android")
Risks
Risk is missing some scenario/semantic in order to ensure Android for .NET is successful. This would be a new interop stack and be narrow in scope, following our Swift, ObjectiveC and WinRT interop solutions in .NET Core.
Metadata
Metadata
Assignees
Type
Projects
Status
No status