Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
49ef2ee
Initial infrastructure for new eh handling in qcalls
davidwrighton Aug 14, 2026
e8d8016
Route QCall exceptions through marshalling
davidwrighton Aug 17, 2026
01c1f90
Limit QCall exception arguments to wrapped calls
davidwrighton Aug 17, 2026
47190b9
Remove excess use of current thread static
davidwrighton Aug 17, 2026
9ed97b6
Fix the build
davidwrighton Aug 17, 2026
35b6717
Fix build
davidwrighton Aug 17, 2026
4b99b55
Initialize QCall exception status
davidwrighton Aug 18, 2026
566879c
Move qcall exception to tls data to avoid the Thread object
davidwrighton Aug 18, 2026
7cf1b46
Merge branch 'main' of https://github.com/dotnet/runtime into fixup_q…
davidwrighton Aug 18, 2026
da22e7b
Preserve QCall IL stub helper signatures
davidwrighton Aug 19, 2026
8432bb3
Fix shared thread ID call formatting
davidwrighton Aug 19, 2026
5457b28
Regenerate CoreCLR WebAssembly call helpers
davidwrighton Aug 19, 2026
780f494
Rename QCall exception status and fix signatures
davidwrighton Aug 19, 2026
0f78144
Merge upstream main into QCall exception changes
davidwrighton Aug 24, 2026
a0f7ea8
Add LibraryImport error handler support
davidwrighton Aug 25, 2026
6ba4092
Use hidden return values for QCall exceptions
davidwrighton Aug 25, 2026
8cd6143
Merge upstream/main into fixup_qcalls
davidwrighton Aug 25, 2026
351c207
Fix Unix XplatEventLogger QCall invocation
davidwrighton Aug 25, 2026
14257f4
Merge upstream/main into fixup_qcalls
davidwrighton Aug 27, 2026
55f2448
Fix QCall exception handle lifetime
davidwrighton Aug 29, 2026
c2b1b18
Merge from upstream main
davidwrighton Aug 31, 2026
6061a85
Address some formatting issues
davidwrighton Aug 31, 2026
2049718
More formatting fixes
davidwrighton Aug 31, 2026
33396e5
Merge branch 'main' into fixup_qcalls
davidwrighton Sep 1, 2026
aa5802e
Address QCall review feedback
davidwrighton Sep 1, 2026
b5c08b0
Use hidden last parameter for QCall errors
davidwrighton Sep 2, 2026
fa08375
Use GetThread in QCall exception handling
davidwrighton Sep 2, 2026
b6907f9
Merge branch 'main' of https://github.com/dotnet/runtime into fixup_q…
davidwrighton Sep 2, 2026
1742816
Restore CompressBound in WebAssembly P/Invoke tables
davidwrighton Sep 2, 2026
e1b823a
Address QCall review feedback
davidwrighton Sep 3, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 17 additions & 13 deletions docs/design/coreclr/botr/corelib.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,29 +77,29 @@ QCalls should be implemented with a C-style method signature. This makes it easi
Do not replicate the comments into your actual QCall implementation. This is for illustrative purposes.

```CSharp
class Foo
partial class Foo
{
// All QCalls should have the following DllImport attribute
[DllImport(RuntimeHelpers.QCall, EntryPoint = "Foo_BarInternal", CharSet = CharSet.Unicode)]

// QCalls should always be static extern.
private static extern bool BarInternal(int flags, string inString, StringHandleOnStack retString);
// QCalls that use BEGIN_QCALL must use the hidden last parameter error handler.
[ErrorHandler(typeof(QCallExceptionStatusMarshaller), ErrorLocation.HiddenLastParameter)]
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Foo_BarInternal", StringMarshalling = StringMarshalling.Utf16)]
[return: MarshalAs(UnmanagedType.Bool)]
private static partial bool BarInternal(int flags, string inString, StringHandleOnStack retString);

// Many QCalls have a thin managed wrapper around them to perform
// as much work prior to the transition as possible. An example would be
// argument validation which is easier in managed than native code.
public string Bar(int flags)
public string Bar(int flags, string inString)
{
if (flags != 0)
throw new ArgumentException("Invalid flags");

string retString = null;
string? retString = null;
// The strings are returned from QCalls by taking address
// of a local variable using StringHandleOnStack
if (!BarInternal(flags, this.Id, new StringHandleOnStack(ref retString)))
// of a local variable using StringHandleOnStack.
if (!BarInternal(flags, inString, new StringHandleOnStack(ref retString)))
FatalError();

return retString;
return retString!;
}
}
```
Expand All @@ -114,7 +114,8 @@ The QCall entrypoint has to be registered in tables in [vm\qcallentrypoints.cpp]

```C++
// All QCalls should be free functions and tagged with QCALLTYPE and extern "C"
extern "C" BOOL QCALLTYPE Foo_BarInternal(int flags, LPCWSTR wszString, QCall::StringHandleOnStack retString)
extern "C" BOOL QCALLTYPE Foo_BarInternal(
int flags, LPCWSTR wszString, QCall::StringHandleOnStack retString, QCallExceptionStatus* qcallError)
{
// All QCalls should have QCALL_CONTRACT.
// It is alias for THROWS; GC_TRIGGERS; MODE_PREEMPTIVE.
Expand All @@ -132,7 +133,7 @@ extern "C" BOOL QCALLTYPE Foo_BarInternal(int flags, LPCWSTR wszString, QCall::S
BOOL retVal = FALSE;

// The body has to be enclosed in BEGIN_QCALL/END_QCALL macro.
// It is necessary for exception handling.
// It initializes qcallError and captures exceptions for the managed error handler.
BEGIN_QCALL;

// Argument validation would ideally be in managed, but in some cases
Expand All @@ -158,6 +159,9 @@ extern "C" BOOL QCALLTYPE Foo_BarInternal(int flags, LPCWSTR wszString, QCall::S
}
```

QCalls that return before entering `BEGIN_QCALL`, including no-op fast paths and code excluded
by platform conditionals, must explicitly set `*qcallError = 0` before returning.

## FCall functional behavior

FCalls allow more flexibility in terms of passing object references around, but with higher code complexity and more opportunities to make mistakes. Additionally, for any FCall of non-trivial length, explicitly poll for whether a garbage collection must occur. Failing to do so will lead to starvation issues if managed code repeatedly calls the FCall method in a tight loop, because FCalls execute while the thread only allows the GC to run in a cooperative manner.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@
<Compile Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\AsyncHelpers.ValueTaskSourceContinuation.cs" />
<Compile Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\AsyncHelpers.RuntimeAsyncYielder.cs" />
<Compile Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\AsyncProfiler.CoreCLR.cs" />
<Compile Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\QCallExceptionStatus.cs" />
<Compile Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\RuntimeAsyncTaskContinuation.cs" />
<Compile Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\RuntimeHelpers.CoreCLR.cs" />
<Compile Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\StaticsHelpers.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ namespace Internal.Runtime.CompilerHelpers
internal static unsafe partial class ThrowHelpers
{
[DoesNotReturn]
[ErrorHandler(typeof(QCallExceptionStatusMarshaller), ErrorLocation.HiddenLastParameter)]
Comment thread
davidwrighton marked this conversation as resolved.
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "ExceptionNative_ThrowAmbiguousResolutionException")]
private static partial void ThrowAmbiguousResolutionException(MethodTable* targetType, MethodTable* interfaceType, void* methodDesc);

Expand All @@ -25,6 +26,7 @@ internal static void ThrowAmbiguousResolutionException(
}

[DoesNotReturn]
[ErrorHandler(typeof(QCallExceptionStatusMarshaller), ErrorLocation.HiddenLastParameter)]
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "ExceptionNative_ThrowEntryPointNotFoundException")]
private static partial void ThrowEntryPointNotFoundException(MethodTable* targetType, MethodTable* interfaceType, void* methodDesc);

Expand All @@ -39,6 +41,7 @@ internal static void ThrowEntryPointNotFoundException(
}

[DoesNotReturn]
[ErrorHandler(typeof(QCallExceptionStatusMarshaller), ErrorLocation.HiddenLastParameter)]
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "ExceptionNative_ThrowMethodAccessException")]
private static partial void ThrowMethodAccessExceptionInternal(void* caller, void* callee);

Expand All @@ -53,6 +56,7 @@ internal static void ThrowMethodAccessException(
}

[DoesNotReturn]
[ErrorHandler(typeof(QCallExceptionStatusMarshaller), ErrorLocation.HiddenLastParameter)]
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "ExceptionNative_ThrowFieldAccessException")]
private static partial void ThrowFieldAccessExceptionInternal(void* caller, void* callee);

Expand All @@ -67,6 +71,7 @@ internal static void ThrowFieldAccessException(
}

[DoesNotReturn]
[ErrorHandler(typeof(QCallExceptionStatusMarshaller), ErrorLocation.HiddenLastParameter)]
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "ExceptionNative_ThrowClassAccessException")]
private static partial void ThrowClassAccessExceptionInternal(void* caller, void* callee);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ namespace Internal
/// </summary>
internal static partial class VersionResilientHashCode
{
[ErrorHandler(typeof(QCallExceptionStatusMarshaller), ErrorLocation.HiddenLastParameter)]
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "VersionResilientHashCode_TypeHashCode")]
private static partial int TypeHashCode(QCallTypeHandle typeHandle);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ private static bool IsKnownHostProperty(string name)
or "PLATFORM_RESOURCE_ROOTS"
or "APP_PATHS";

[ErrorHandler(typeof(QCallExceptionStatusMarshaller), ErrorLocation.HiddenLastParameter)]
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "AppContext_TryGetHostPropertyValue", StringMarshalling = StringMarshalling.Utf16)]
[return: MarshalAs(UnmanagedType.Bool)]
private static partial bool TryGetHostPropertyValue(string name, StringHandleOnStack retValue);
Expand Down
5 changes: 5 additions & 0 deletions src/coreclr/System.Private.CoreLib/src/System/ArgIterator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public ArgIterator(RuntimeArgumentHandle arglist)
Init(ThisPtr, cookie);
}

[ErrorHandler(typeof(QCallExceptionStatusMarshaller), ErrorLocation.HiddenLastParameter)]
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "ArgIterator_Init")]
private static partial void Init(ArgIterator* thisPtr, IntPtr cookie);

Expand All @@ -55,6 +56,7 @@ public ArgIterator(RuntimeArgumentHandle arglist, void* ptr)
Init(ThisPtr, cookie, ptr);
}

[ErrorHandler(typeof(QCallExceptionStatusMarshaller), ErrorLocation.HiddenLastParameter)]
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "ArgIterator_Init2")]
private static partial void Init(ArgIterator* thisPtr, IntPtr cookie, void* ptr);

Expand All @@ -81,6 +83,7 @@ public TypedReference GetNextArg()
return result;
}

[ErrorHandler(typeof(QCallExceptionStatusMarshaller), ErrorLocation.HiddenLastParameter)]
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "ArgIterator_GetNextArg")]
private static partial void GetNextArg(ArgIterator* thisPtr, TypedReference* pResult);

Expand Down Expand Up @@ -116,6 +119,7 @@ public TypedReference GetNextArg(RuntimeTypeHandle rth)
return result;
}

[ErrorHandler(typeof(QCallExceptionStatusMarshaller), ErrorLocation.HiddenLastParameter)]
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "ArgIterator_GetNextArg2")]
private static partial void GetNextArg(ArgIterator* thisPtr, QCallTypeHandle rth, TypedReference* pResult);

Expand All @@ -141,6 +145,7 @@ public RuntimeTypeHandle GetNextArgType()
return RuntimeTypeHandle.FromIntPtr(GetNextArgType(ThisPtr));
}

[ErrorHandler(typeof(QCallExceptionStatusMarshaller), ErrorLocation.HiddenLastParameter)]
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "ArgIterator_GetNextArgType")]
private static partial IntPtr GetNextArgType(ArgIterator* thisPtr);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ namespace System
// IList<U> and IReadOnlyList<U>, where T : U dynamically. See the SZArrayHelper class for details.
public abstract partial class Array : ICloneable, IList, IStructuralComparable, IStructuralEquatable
{
[ErrorHandler(typeof(QCallExceptionStatusMarshaller), ErrorLocation.HiddenLastParameter)]
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Array_CreateInstance")]
private static unsafe partial void InternalCreate(QCallTypeHandle type, int rank, int* pLengths, int* pLowerBounds,
[MarshalAs(UnmanagedType.Bool)] bool fromArrayType, ObjectHandleOnStack retArray);
Expand All @@ -35,6 +36,7 @@ private static unsafe Array InternalCreateFromArrayType(RuntimeType arrayType, i
return retArray!;
}

[ErrorHandler(typeof(QCallExceptionStatusMarshaller), ErrorLocation.HiddenLastParameter)]
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Array_Ctor")]
private static unsafe partial void Ctor(MethodTable* pArrayMT, uint dwNumArgs, int* pArgList, ObjectHandleOnStack retArray);

Expand Down Expand Up @@ -349,6 +351,7 @@ internal sealed unsafe partial class ArrayInitializeCache : RuntimeType.IGeneric
{
internal readonly delegate*<ref byte, void> ConstructorEntrypoint;

[ErrorHandler(typeof(QCallExceptionStatusMarshaller), ErrorLocation.HiddenLastParameter)]
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Array_GetElementConstructorEntrypoint")]
private static partial delegate*<ref byte, void> GetElementConstructorEntrypoint(QCallTypeHandle arrayType);

Expand Down
1 change: 1 addition & 0 deletions src/coreclr/System.Private.CoreLib/src/System/CLRConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ internal static bool GetBoolValue(string switchName, out bool exist)
return GetConfigBoolValue(switchName, out exist);
}

[ErrorHandler(typeof(QCallExceptionStatusMarshaller), ErrorLocation.HiddenLastParameter)]
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "ClrConfig_GetConfigBoolValue", StringMarshalling = StringMarshalling.Utf16)]
[return: MarshalAs(UnmanagedType.Bool)]
private static partial bool GetConfigBoolValue(string configSwitchName, [MarshalAs(UnmanagedType.Bool)] out bool exist);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ namespace System
{
internal sealed partial class ComAwareWeakReference
{
[ErrorHandler(typeof(QCallExceptionStatusMarshaller), ErrorLocation.HiddenLastParameter)]
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "ComWeakRefToObject")]
private static partial void ComWeakRefToObject(IntPtr pComWeakRef, ObjectHandleOnStack retRcw);

Expand Down Expand Up @@ -38,6 +39,7 @@ internal static bool PossiblyComObject(object target)
#endif // FEATURE_COMINTEROP
}

[ErrorHandler(typeof(QCallExceptionStatusMarshaller), ErrorLocation.HiddenLastParameter)]
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "ObjectToComWeakRef")]
private static partial IntPtr ObjectToComWeakRef(ObjectHandleOnStack retRcw);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,7 @@ private struct BindToMethodDetails
public GCHandle loaderAllocatorGCHandle; // The loader allocator needed if the delegate needs to keep it alive
}

[ErrorHandler(typeof(QCallExceptionStatusMarshaller), ErrorLocation.HiddenLastParameter)]
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Delegate_BindToMethodName", StringMarshalling = StringMarshalling.Utf8)]
[return: MarshalAs(UnmanagedType.Bool)]
private static partial bool BindToMethodName(MethodTable* pDelegateMT, MethodTable *pTargetMT, QCallTypeHandle methodType, string method, DelegateBindingFlags flags, ObjectHandleOnStack targetParameter, out BindToMethodDetails bindToMethodDetails);
Expand Down Expand Up @@ -567,6 +568,7 @@ private bool BindToMethodInfo(object? target, IRuntimeMethodInfo method, Runtime
return ret;
}

[ErrorHandler(typeof(QCallExceptionStatusMarshaller), ErrorLocation.HiddenLastParameter)]
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Delegate_BindToMethodInfo")]
[return: MarshalAs(UnmanagedType.Bool)]
private static partial bool BindToMethodInfo(MethodTable* pDelegateMT, MethodTable *pTargetMT, RuntimeMethodHandleInternal method, QCallTypeHandle methodType, DelegateBindingFlags flags, ObjectHandleOnStack targetParameter, out BindToMethodDetails bindToMethodDetails);
Expand Down Expand Up @@ -640,12 +642,14 @@ private void DelegateConstruct(object target, IntPtr method)
_target = target;
}

[ErrorHandler(typeof(QCallExceptionStatusMarshaller), ErrorLocation.HiddenLastParameter)]
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Delegate_Construct")]
private static partial void Construct(MethodTable* pDelegateMT, MethodTable* pTargetMT, IntPtr method, out BindToMethodDetails bindToMethodDetails);

[MethodImpl(MethodImplOptions.InternalCall)]
private static extern unsafe void* GetMulticastInvoke(MethodTable* pMT);

[ErrorHandler(typeof(QCallExceptionStatusMarshaller), ErrorLocation.HiddenLastParameter)]
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Delegate_GetMulticastInvokeSlow")]
private static unsafe partial void* GetMulticastInvokeSlow(MethodTable* pMT);

Expand Down Expand Up @@ -681,6 +685,7 @@ private static unsafe IRuntimeMethodInfo CreateMethodInfo(MethodDesc* methodDesc
return methodInfo!;
}

[ErrorHandler(typeof(QCallExceptionStatusMarshaller), ErrorLocation.HiddenLastParameter)]
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Delegate_CreateMethodInfo")]
private static unsafe partial void CreateMethodInfo(MethodDesc* methodDesc, ObjectHandleOnStack retMethodInfo);

Expand All @@ -691,6 +696,7 @@ private static unsafe IRuntimeMethodInfo CreateMethodInfo(MethodDesc* methodDesc
return GetMethodDesc(ObjectHandleOnStack.Create(ref instance));
}

[ErrorHandler(typeof(QCallExceptionStatusMarshaller), ErrorLocation.HiddenLastParameter)]
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Delegate_GetMethodDesc")]
private static unsafe partial MethodDesc* GetMethodDesc(ObjectHandleOnStack instance);

Expand Down Expand Up @@ -887,6 +893,7 @@ internal static IntPtr AdjustTarget(object target, IntPtr methodPtr)
}
}

[ErrorHandler(typeof(QCallExceptionStatusMarshaller), ErrorLocation.HiddenLastParameter)]
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Delegate_AdjustTarget")]
private static partial IntPtr AdjustTarget(MethodTable* targetMT, IntPtr methodPtr);

Expand All @@ -896,6 +903,7 @@ internal void InitializeVirtualCallStub(IntPtr methodPtr)
InitializeVirtualCallStub(ObjectHandleOnStack.Create(ref d), methodPtr);
}

[ErrorHandler(typeof(QCallExceptionStatusMarshaller), ErrorLocation.HiddenLastParameter)]
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Delegate_InitializeVirtualCallStub")]
private static partial void InitializeVirtualCallStub(ObjectHandleOnStack d, IntPtr methodPtr);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ namespace System.Diagnostics
{
public static partial class Debugger
{
[ErrorHandler(typeof(QCallExceptionStatusMarshaller), ErrorLocation.HiddenLastParameter)]
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "DebugDebugger_Break")]
private static partial void BreakInternal();

Expand Down Expand Up @@ -83,6 +84,7 @@ static void NotifyOfCrossThreadDependencySlow()
// Posts a custom notification for the attached debugger. If there is no
// debugger attached, has no effect. The debugger may or may not
// report the notification depending on its settings.
[ErrorHandler(typeof(QCallExceptionStatusMarshaller), ErrorLocation.HiddenLastParameter)]
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "DebugDebugger_CustomNotification")]
private static partial void CustomNotification(ObjectHandleOnStack data);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ private void BuildStackFrame(int skipFrames, bool needFileInfo)
private static bool AppendStackFrameWithoutMethodBase(StringBuilder sb) => false;
#pragma warning restore IDE0060

[ErrorHandler(typeof(QCallExceptionStatusMarshaller), ErrorLocation.HiddenLastParameter)]
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "StackFrame_GetMethodDescFromNativeIP")]
private static partial RuntimeMethodHandleInternal GetMethodDescFromNativeIP(IntPtr ip);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ namespace System.Diagnostics
{
public partial class StackTrace
{
[ErrorHandler(typeof(QCallExceptionStatusMarshaller), ErrorLocation.HiddenLastParameter)]
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "StackTrace_GetStackFramesInternal")]
private static partial void GetStackFramesInternal(ObjectHandleOnStack sfh, [MarshalAs(UnmanagedType.Bool)] bool fNeedFileInfo, ObjectHandleOnStack e);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ namespace System
{
public abstract partial class Enum
{
[ErrorHandler(typeof(QCallExceptionStatusMarshaller), ErrorLocation.HiddenLastParameter)]
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Enum_GetValuesAndNames")]
private static partial void GetEnumValuesAndNames(QCallTypeHandle enumType, ObjectHandleOnStack values, ObjectHandleOnStack names, Interop.BOOL getNames);

Expand Down
Loading
Loading