New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[API Proposal]: Add support for converting to/from IntPtr
for some handles
#67090
Comments
I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label. |
I guess the |
This is a good point, I'll add it to the risks section. It's definitely something that a user of the API would need to be keenly aware of. |
🍝 Just throwing this out for consideration: Should the public entrypoint for this API be placed somewhere under |
Tagging subscribers to this area: @dotnet/interop-contrib Issue DetailsBackground and motivationThe Currently, this API is Having a way to retrieve the original API Proposalnamespace System
{
public abstract partial class Type
{
public static Type? GetTypeFromHandleUnsafe(IntPtr handle);
}
} API Usagevar api = new NativeAPI
{
GetTypeHandle = &GetTypeHandle,
GetFullTypeName = &GetFullTypeName,
GetFunctionPointer = &GetFunctionPointer
};
// This native method may be interested in querying for
// pointers to UnmanagedCallersOnly methods to invoke.
SomeNativeMethod(&api); [UnmanagedCallersOnly]
static IntPtr GetTypeHandle(IntPtr typeName)
{
return Type.GetType(Marshal.PtrToStringUni(typeName)).TypeHandle.Value;
}
[UnmanagedCallersOnly]
static IntPtr GetFunctionPointer(IntPtr type, IntPtr methodName)
{
var type = Type.GetTypeFromHandleUnsafe(type);
var method = type.GetMethod(Marshal.PtrToStringUni(methodName), BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
return method.MethodHandle.GetFunctionPointer();
}
[UnmanagedCallersOnly]
static IntPtr GetFullTypeName(IntPtr type)
{
return Marshal.StringToHGlobalUni(Type.GetTypeFromHandleUnsafe(type)?.FullName);
} Alternative DesignsNo response RisksBeing an unmanaged pointer,
|
That sounds reasonable to me -- |
@jkotas or @davidwrighton Can either of you imagine a scenario where the TypeHandle wouldn't be static? Unless unloaded that is. I am trying to determine if there is any chance of the |
It is very likely that every realistic .NET runtime implementation has stable In a hypothetical case where .NET runtime implementation does not have natural stable This API is about marshaling |
Thoughts on adding this to public struct RuntimeTypeHandle
{
+ public static RuntimeTypeHandle FromIntPtr(IntPtr value);
} |
I like putting it on |
I agree, it makes more sense to add it to |
I agree that |
Yep. That makes perfect sense. @DaZombieKiller I'm going to update the proposal with this approach and then move it to ready for review. Please feel free to push back if you have another opinion. |
For the sake of parity, it may also be useful to expose APIs for public struct RuntimeFieldHandle
{
+ public static RuntimeFieldHandle FromIntPtr(IntPtr value);
+ public static IntPtr ToIntPtr(RuntimeFieldHandle value);
}
public struct RuntimeMethodHandle
{
+ public static RuntimeMethodHandle FromIntPtr(IntPtr value);
+ public static IntPtr ToIntPtr(RuntimeMethodHandle value);
} |
@DaZombieKiller Sure. I'll add that as well. |
Type.GetTypeFromHandleUnsafe
publicIntPtr
for some handles
namespace System;
public struct RuntimeTypeHandle
{
public static RuntimeTypeHandle FromIntPtr(IntPtr value);
public static IntPtr ToIntPtr(RuntimeTypeHandle value);
}
public struct RuntimeFieldHandle
{
public static RuntimeFieldHandle FromIntPtr(IntPtr value);
public static IntPtr ToIntPtr(RuntimeFieldHandle value);
}
public struct RuntimeMethodHandle
{
public static RuntimeMethodHandle FromIntPtr(IntPtr value);
public static IntPtr ToIntPtr(RuntimeMethodHandle value);
} |
Tagging subscribers to this area: @dotnet/area-system-runtime Issue DetailsBackground and motivationThe Currently, this API is Having a way to retrieve the original API Proposalpublic struct RuntimeTypeHandle
{
+ public static RuntimeTypeHandle FromIntPtr(IntPtr value);
+ public static IntPtr ToIntPtr(RuntimeTypeHandle value);
}
public struct RuntimeFieldHandle
{
+ public static RuntimeFieldHandle FromIntPtr(IntPtr value);
+ public static IntPtr ToIntPtr(RuntimeFieldHandle value);
}
public struct RuntimeMethodHandle
{
+ public static RuntimeMethodHandle FromIntPtr(IntPtr value);
+ public static IntPtr ToIntPtr(RuntimeMethodHandle value);
} API Usagevar api = new NativeAPI
{
GetTypeHandle = &GetTypeHandle,
GetFullTypeName = &GetFullTypeName,
GetFunctionPointer = &GetFunctionPointer
};
// This native method may be interested in querying for
// pointers to UnmanagedCallersOnly methods to invoke.
SomeNativeMethod(&api); [UnmanagedCallersOnly]
static IntPtr GetTypeHandle(IntPtr typeName)
{
return Type.GetType(Marshal.PtrToStringUni(typeName)).TypeHandle.Value;
}
[UnmanagedCallersOnly]
static IntPtr GetFunctionPointer(IntPtr type, IntPtr methodName)
{
var type = Type.GetTypeFromHandle(RuntimeTypeHandle.FromIntPtr(type));
var method = type.GetMethod(Marshal.PtrToStringUni(methodName), BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
return method.MethodHandle.GetFunctionPointer();
}
[UnmanagedCallersOnly]
static IntPtr GetFullTypeName(IntPtr type)
{
return Marshal.StringToHGlobalUni(Type.GetTypeFromHandle(RuntimeTypeHandle.FromIntPtr(type))?.FullName);
} Alternative DesignsNo response RisksBeing an unmanaged pointer,
|
Background and motivation
The
Type.GetTypeFromHandleUnsafe
method allows you to retrieve theType
object associated with a type handle pointer retrieved viaRuntimeTypeHandle.Value
.Currently, this API is
internal
with nopublic
-facing equivalent. This means there is currently no safe way for you to get the originalType
orRuntimeTypeHandle
value back, leading to theRuntimeTypeHandle.Value
property being of little use.Having a way to retrieve the original
Type
orRuntimeTypeHandle
would also allow the type handle pointer to be used to easily pass types to native code (such as when writing a custom runtime host).API Proposal
API Usage
Alternative Designs
No response
Risks
Being an unmanaged pointer,
RuntimeTypeHandle.Value
will not keep a collectible type alive. This would need to be clearly called out in documentation and could be a potential problem when the API is not used correctly.The text was updated successfully, but these errors were encountered: