I've seen a few examples of how to do this from C++ an unmanaged dll, to a C++ managed CLR dll. I currently have a C++ dll (NetPcapWrap), that references a C dll (npcap.dll). Since the npcap.dll is written in C I cannot compile with CLR so NetPcapWrap is unmanaged. My .Net Forms application references the NetPcapWrap.dll using pInvoke to gets information from the npcap.dll.
Within the npcap.dll is a looping function that writes out data to std::out what I need to do instead call a delegate of the .Net windows Forms app.
I've seen one potential solution https://www.codeproject.com/tips/695387/calling-csharp-net-methods-from-unmanaged-c-cplusp but this would require yet another dll that is compiled with CLR enabled.
Is there a way to do "reverse" pInvoke from an unmanaged C++ dll to a .Net Winforms application?
Sorry, I don't have any code to post because I can't figure out how to write the potion. I can share how I pInvoke the C++ dll but that is not my question.
Thanks

you need the C# code to send a delegate to a C function that expects a function pointer, then store it in some global.
and C# needs to also store this delegate in a static variable to prevent the GC from cleaning it, maybe even pin the delegate.
on C/C++ side.
then on C# side
then your main app needs to call them.
as a bonus, this also works on linux/macos where managed C++ dlls don't exist. (tested with dotnet 6 and 8)
while this small example works, you may need to pin any involved C# object from moving using GCHandle, and maybe even pin the delegate to prevent C# Garbage collector from moving it.
note that you cannot allow C++ exceptions to leak into C#, you also cannot allow C# exceptions to leak into C++.