C# function pointers causes access violation upon calling from C++

In the following bit of code I’m using C# function pointers to omit using a delegate type, for faster performance. The code works fine when I use a delegate type marshalled as a function pointer, no exception no issues. However when changing it from a delegate to a function pointer it sometimes throws an access violation.

Code is modified to remove namespaces and prefixes not relevant to the question

public static class Engine
{
    // Causing issues with sometimes throwing access violation
    [DllImport("engine", CallingConvention = CallingConvention.Cdecl)]
    public static unsafe extern UInt32 EventScheduler_ScheduleLocalEvent(
        int priority, UInt64 delay, delegate* unmanaged[Cdecl]<nint, void> callback, nint obj);

    // Works fine every time, but is much slower seems due to delegate instatiations
    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
    public delegate void EventScheduler_ScheduleLocalEvent_callbackDelegate(IntPtr obj);
    [DllImport("engine", CallingConvention = CallingConvention.Cdecl)]
    public static unsafe extern UInt32 EventScheduler_ScheduleLocalEvent(
        int priority,
        UInt64 delay,
        [MarshalAs(UnmanagedType.FunctionPtr)] EventScheduler_ScheduleLocalEvent_callbackDelegate callback,
        IntPtr obj);

}

public static class EventScheduler
{
    public delegate void EventCallback();

    // attribute is only present in the function pointer senario
    [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvCdecl ) }, EntryPoint = "ScheduleLocalEvent_EventCallbackFunction")]
    private static void ScheduleLocalEvent_EventCallbackFunction(nint handlePtr)
    {
        Thread.BeginThreadAffinity();
        GCHandle handle = GCHandle.FromIntPtr(handlePtr);
        var cb          = (EventScheduler.EventCallback)handle.Target!;
        cb();
        handle.Free();
        Thread.EndThreadAffinity();
    }
    public static UInt32 ScheduleLocalEvent(int priority, SimulationTime delayTime, EventCallback eventCallback)
    {
        GCHandle handle  = GCHandle.Alloc(eventCallback, GCHandleType.Normal);
        IntPtr handlePtr = GCHandle.ToIntPtr(handle);
        unsafe
        {
            return Engine.EventScheduler_ScheduleLocalEvent(
                priority, delayTime, &ScheduleLocalEvent_EventCallbackFunction, handlePtr);
        }
    }

}

On the C++ side

#define API extern "C" __declspec(dllexport)

API uint32_t EventScheduler_ScheduleLocalEvent(int priority, uint64_t delay, void(__cdecl* callback)(void* obj), void* obj)
{
    ERSAssert(Ers::Core::InsideSubModel());
    Core::SyncManagerBase& syncManager = Ers::Core::GetSyncManagerBase();
    return syncManager.ScheduleEvent(priority, delay, [callback, obj]() { callback(obj); });
}

The folowing output is given when the program is ran.

AWealthOfRows.exe (process 39016) exited with code -1073741819.

With the following output

' AWealthOfRows.exe' (Win32): Loaded 'C:ProjectsTestingEnterprise_Resource_SimulatorbindingsCSharpAWealthOfRowsbinDebugnet8.0AWealthOfRows.exe'. 'AWealthOfRows.exe' (Win32): Loaded 'C:WindowsSystem32ntdll.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:WindowsSystem32kernel32.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:WindowsSystem32KernelBase.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:WindowsSystem32user32.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:WindowsSystem32win32u.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:WindowsSystem32gdi32.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:WindowsSystem32gdi32full.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:WindowsSystem32msvcp_win.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:WindowsSystem32ucrtbase.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:WindowsSystem32shell32.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:WindowsSystem32advapi32.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:WindowsSystem32msvcrt.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:WindowsSystem32sechost.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:WindowsSystem32bcrypt.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:WindowsSystem32rpcrt4.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:WindowsSystem32imm32.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:Program Filesdotnethostfxr9.0.0-preview.3.24172.9hostfxr.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:Program FilesdotnetsharedMicrosoft.NETCore.App8.0.5hostpolicy.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:Program FilesdotnetsharedMicrosoft.NETCore.App8.0.5coreclr.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:WindowsSystem32ole32.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:WindowsSystem32combase.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:WindowsSystem32oleaut32.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:WindowsSystem32bcryptprimitives.dll'. The thread 41728 has exited with code 0 (0x0). 'AWealthOfRows.exe' (Win32): Loaded 'C:Program FilesdotnetsharedMicrosoft.NETCore.App8.0.5System.Private.CoreLib.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:Program FilesdotnetsharedMicrosoft.NETCore.App8.0.5clrjit.dll'. 'AWealthOfRows.exe' (CoreCLR: DefaultDomain): Loaded 'C:Program FilesdotnetsharedMicrosoft.NETCore.App8.0.5System.Private.CoreLib.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:WindowsSystem32kernel.appcore.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:ProjectsTestingEnterprise_Resource_SimulatorbindingsCSharpAWealthOfRowsbinDebugnet8.0AWealthOfRows.dll'. The thread 41464 has exited with code 0 (0x0). 'AWealthOfRows.exe' (CoreCLR: clrhost): Loaded 'C:ProjectsTestingEnterprise_Resource_SimulatorbindingsCSharpAWealthOfRowsbinDebugnet8.0AWealthOfRows.dll'. Symbols loaded. 'AWealthOfRows.exe' (Win32): Loaded 'C:Program FilesdotnetsharedMicrosoft.NETCore.App8.0.5System.Runtime.dll'. 'AWealthOfRows.exe' (CoreCLR: clrhost): Loaded 'C:Program FilesdotnetsharedMicrosoft.NETCore.App8.0.5System.Runtime.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:WindowsSystem32icu.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:Program FilesMicrosoft Visual Studio2022CommunityCommon7IDECommonExtensionsMicrosoftHotReloadMicrosoft.Extensions.DotNetDeltaApplier.dll'. 'AWealthOfRows.exe' (CoreCLR: clrhost): Loaded 'c:program filesmicrosoft visual studio2022communitycommon7idecommonextensionsmicrosofthotreloadMicrosoft.Extensions.DotNetDeltaApplier.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:Program FilesdotnetsharedMicrosoft.NETCore.App8.0.5System.IO.Pipes.dll'. 'AWealthOfRows.exe' (CoreCLR: clrhost): Loaded 'C:Program FilesdotnetsharedMicrosoft.NETCore.App8.0.5System.IO.Pipes.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:Program FilesdotnetsharedMicrosoft.NETCore.App8.0.5System.Linq.dll'. 'AWealthOfRows.exe' (CoreCLR: clrhost): Loaded 'C:Program FilesdotnetsharedMicrosoft.NETCore.App8.0.5System.Linq.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:Program FilesdotnetsharedMicrosoft.NETCore.App8.0.5System.Collections.dll'. 'AWealthOfRows.exe' (CoreCLR: clrhost): Loaded 'C:Program FilesdotnetsharedMicrosoft.NETCore.App8.0.5System.Collections.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:Program FilesdotnetsharedMicrosoft.NETCore.App8.0.5System.Console.dll'. 'AWealthOfRows.exe' (CoreCLR: clrhost): Loaded 'C:Program FilesdotnetsharedMicrosoft.NETCore.App8.0.5System.Console.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:Program FilesdotnetsharedMicrosoft.NETCore.App8.0.5System.Threading.dll'. 'AWealthOfRows.exe' (CoreCLR: clrhost): Loaded 'C:Program FilesdotnetsharedMicrosoft.NETCore.App8.0.5System.Threading.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:Program FilesdotnetsharedMicrosoft.NETCore.App8.0.5System.Runtime.InteropServices.dll'. 'AWealthOfRows.exe' (CoreCLR: clrhost): Loaded 'C:Program FilesdotnetsharedMicrosoft.NETCore.App8.0.5System.Runtime.InteropServices.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:Program FilesdotnetsharedMicrosoft.NETCore.App8.0.5System.Threading.Overlapped.dll'. 'AWealthOfRows.exe' (CoreCLR: clrhost): Loaded 'C:Program FilesdotnetsharedMicrosoft.NETCore.App8.0.5System.Threading.Overlapped.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:Program FilesdotnetsharedMicrosoft.NETCore.App8.0.5System.Security.AccessControl.dll'. 'AWealthOfRows.exe' (CoreCLR: clrhost): Loaded 'C:Program FilesdotnetsharedMicrosoft.NETCore.App8.0.5System.Security.AccessControl.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:Program FilesdotnetsharedMicrosoft.NETCore.App8.0.5System.Security.Principal.Windows.dll'. 'AWealthOfRows.exe' (CoreCLR: clrhost): Loaded 'C:Program FilesdotnetsharedMicrosoft.NETCore.App8.0.5System.Security.Principal.Windows.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:WindowsSystem32ntmarta.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:Program FilesdotnetsharedMicrosoft.NETCore.App8.0.5System.Security.Claims.dll'. 'AWealthOfRows.exe' (CoreCLR: clrhost): Loaded 'C:Program FilesdotnetsharedMicrosoft.NETCore.App8.0.5System.Security.Claims.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:Program FilesdotnetsharedMicrosoft.NETCore.App8.0.5System.Runtime.Loader.dll'. 'AWealthOfRows.exe' (CoreCLR: clrhost): Loaded 'C:Program FilesdotnetsharedMicrosoft.NETCore.App8.0.5System.Runtime.Loader.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:ProjectsTestingEnterprise_Resource_SimulatorbindingsCSharpAWealthOfRowsbinDebugnet8.0Ers.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:Program FilesdotnetsharedMicrosoft.NETCore.App8.0.5System.Collections.Concurrent.dll'. 'AWealthOfRows.exe' (CoreCLR: clrhost): Loaded 'C:ProjectsTestingEnterprise_Resource_SimulatorbindingsCSharpAWealthOfRowsbinDebugnet8.0Ers.dll'. Symbols loaded. 'AWealthOfRows.exe' (CoreCLR: clrhost): Loaded 'C:Program FilesdotnetsharedMicrosoft.NETCore.App8.0.5System.Collections.Concurrent.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:ProjectsTestingEnterprise_Resource_SimulatorbindingsCSharpAWealthOfRowsbinDebugnet8.0ers-engine.dll'. Symbols loaded. 'AWealthOfRows.exe' (Win32): Loaded 'C:WindowsSystem32setupapi.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:WindowsSystem32winmm.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:WindowsSystem32version.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:WindowsSystem32vcruntime140d.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:WindowsSystem32msvcp140d.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:WindowsSystem32vcruntime140_1d.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:WindowsSystem32ucrtbased.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:WindowsSystem32cfgmgr32.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:Program FilesdotnetsharedMicrosoft.NETCore.App8.0.5System.Diagnostics.Process.dll'. 'AWealthOfRows.exe' (CoreCLR: clrhost): Loaded 'C:Program FilesdotnetsharedMicrosoft.NETCore.App8.0.5System.Diagnostics.Process.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:Program FilesdotnetsharedMicrosoft.NETCore.App8.0.5System.ComponentModel.Primitives.dll'. 'AWealthOfRows.exe' (CoreCLR: clrhost): Loaded 'C:Program FilesdotnetsharedMicrosoft.NETCore.App8.0.5System.ComponentModel.Primitives.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:Program FilesdotnetsharedMicrosoft.NETCore.App8.0.5System.Memory.dll'. 'AWealthOfRows.exe' (CoreCLR: clrhost): Loaded 'C:Program FilesdotnetsharedMicrosoft.NETCore.App8.0.5System.Memory.dll'. 'AWealthOfRows.exe' (Win32): Loaded 'C:Program FilesdotnetsharedMicrosoft.NETCore.App8.0.5System.Text.Encoding.Extensions.dll'. The thread 20540 has exited with code 0 (0x0). The thread 23312 has exited with code 0 (0x0). 'AWealthOfRows.exe' (CoreCLR: clrhost): Loaded 'C:Program FilesdotnetsharedMicrosoft.NETCore.App8.0.5System.Text.Encoding.Extensions.dll'. The thread 9224 has exited with code 0 (0x0). 'AWealthOfRows.exe' (Win32): Loaded 'C:Program FilesdotnetsharedMicrosoft.NETCore.App8.0.5System.Threading.Thread.dll'. 'AWealthOfRows.exe' (CoreCLR: clrhost): Loaded 'C:Program FilesdotnetsharedMicrosoft.NETCore.App8.0.5System.Threading.Thread.dll'. Exception thrown at 0x000001F303570860 in AWealthOfRows.exe: 0xC0000005: Access violation reading location 0x000001F30385FB32. The Common Language Runtime cannot stop at this exception. Common causes include: incorrect COM interop marshalling and memory corruption. To investigate further use native-only debugging. Unhandled exception at 0x000001F303570860 in AWealthOfRows.exe: 0xC0000005: Access violation reading location 0x000001F30385FB32. The Common Language Runtime cannot stop at this exception. Common causes include: incorrect COM interop marshalling and memory corruption. To investigate further use native-only debugging. The thread '.NET Counter Poller' (35516) has exited with code 3221225477 (0xc0000005). The thread '.NET TP Gate' (24688) has exited with code 3221225477 (0xc0000005). The thread 33416 has exited with code 3221225477 (0xc0000005). The thread '.NET Finalizer' (38504) has exited with code 3221225477 (0xc0000005). The thread '.NET EventPipe' (23352) has exited with code 3221225477 (0xc0000005). The thread 36944 has exited with code 3221225477 (0xc0000005). The thread 30968 has exited with code 3221225477 (0xc0000005). The thread 3560 has exited with code 3221225477 (0xc0000005). The thread 41012 has exited with code 3221225477 (0xc0000005). The thread 13568 has exited with code 3221225477 (0xc0000005). The thread 22992 has exited with code 3221225477 (0xc0000005). The thread '.NET TP Worker' (38436) has exited with code 3221225477 (0xc0000005). The thread 41284 has exited with code 3221225477 (0xc0000005). The thread 40972 has exited with code 3221225477 (0xc0000005). The thread 40980 has exited with code 3221225477 (0xc0000005). The thread 41972 has exited with code 3221225477 (0xc0000005). The thread 39600 has exited with code 3221225477 (0xc0000005). The thread 41096 has exited with code 3221225477 (0xc0000005). The thread 41968 has exited with code 3221225477 (0xc0000005). The thread 7472 has exited with code 3221225477 (0xc0000005). The thread '.NET ThreadPool IO' (36056) has exited with code 3221225477 (0xc0000005). The thread 16184 has exited with code 3221225477 (0xc0000005). The thread 11736 has exited with code 3221225477 (0xc0000005). The thread '.NET TP Worker' (33156) has exited with code 3221225477 (0xc0000005). The thread '.NET TP Worker' (5368) has exited with code 3221225477 (0xc0000005). The thread '.NET ThreadPool IO' (22304) has exited with code 3221225477 (0xc0000005). The thread '.NET TP Worker' (42112) has exited with code 3221225477 (0xc0000005). The thread 40516 has exited with code 3221225477 (0xc0000005). The thread '.NET Tiered Compilation Worker' (2424) has exited with code 3221225477 (0xc0000005). The program '[39016] AWealthOfRows.exe' has exited with code 3221225477 (0xc0000005) 'Access violation'.

I have tried debugging, but when the issue occurs. In which case C++ calls the callback, but before it entering the function’s scope the exception is thrown, but immediately returns with an error code.

For sake of debugging I’ve tried switching the calling convention from cdecl to stdcall to see if it has to do with stack corruption.

My assumptions are that:

  • static functions marked with [UnmanagedCallersOnly] have a static address, especially when an entrypoint is defined.
  • Thread.BeginThreadAffinity() followed by Thread.EndThreadAffinity() ensure that an unmanaged thread can sucessfully start excuting managed code.

Good to know:

  • The function is being invoked by a thread not created in C#, there are many threads calling this function

Looking at the documentation for function pointers here I can’t seem to figure out if I am not following the standard or if there is just an issue with C#’s implementation.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật