FYI, I run managed code from a VEH callback every frame. I'd be curious to see what the restriction is; I'm sure that it's non-standard behavior, but *shrug* it seems to work for me.
Code:
LONG WINAPI ExceptionHandler(PEXCEPTION_POINTERS ExInfo)
{
if (ExInfo && ExInfo->ExceptionRecord && ExInfo->ContextRecord)
{
if (((ExInfo->ContextRecord->Dr6 & 1) == 1) || ((ExInfo->ContextRecord->Dr6 & 2) == 2) || ((ExInfo->ContextRecord->Dr6 & 4) == 4) || ((ExInfo->ContextRecord->Dr6 & 8) == 8))
{
ExInfo->ContextRecord->Dr6 &= ~0xF; // have to disable the bits manually
if (ExInfo->ExceptionRecord->ExceptionCode == STATUS_SINGLE_STEP && ExInfo->ExceptionRecord->ExceptionAddress == GetRebasedAddress<PVOID>(CGGameUI__OnTerrainClick))
{
ExInfo->ContextRecord->EFlags |= 0x10000; // set the resume flag so we don't loop forever
ExInfo->ContextRecord->EFlags &= ~0x100; // turn off single-step flag (just in case!)
float *pClickStruct = *(float **)(ExInfo->ContextRecord->Esp + 4);
msclr::call_in_appdomain(dwDefaultAppDomainId, &UnmanagedNotifyManagedCodeOfClick, pClickStruct[2], pClickStruct[3], pClickStruct[4]);
PS: yes, I know, fugly code. I don't care
... it works, and I never have to touch it, so it never gets refactored.