'get'相当于_set_se_translator?

Meh*_*dad 2 c++ winapi seh structured-exception visual-c++

我需要使用当前翻译手动翻译结构化异常.

我如何"获得"某人设定的价值_set_se_translator

Meh*_*dad 5

更好(新)的方式

我一开始并没有意识到这一点,但SE翻译是线程本地的,而不是整个流程.

所以这实际上是最好(也是最简单)的解决方案:

_se_translator_function _get_se_translator(void) {
    _se_translator_function translator = _set_se_translator(NULL);  // temporary
    _set_se_translator(translator);  // Restore the old value
    return translator;
}
Run Code Online (Sandbox Code Playgroud)

Hacky(旧)方式

没有直接的方法可以做到这一点,但是如果你要冒一些不兼容的风险并深入研究Visual C运行时的内部,你可以破解这样的解决方案:

_se_translator_function __cdecl _get_se_translator(void) {
    unsigned char const *p = (unsigned char const *)(&__uncaught_exception);
    struct _tiddata {
        unsigned long _tid;
        void *_thandle;
        int _terrno; unsigned long _tdoserrno;
        unsigned int _fpds;
        unsigned long _holdrand;
        char *_token; wchar_t *_wtoken;
        unsigned char *_mtoken;
        char *_errmsg; wchar_t *_werrmsg;
        char *_namebuf0; wchar_t *_wnamebuf0;
        char *_namebuf1; wchar_t *_wnamebuf1;
        char *_asctimebuf; wchar_t *_wasctimebuf;
        void *_gmtimebuf;
        char *_cvtbuf;
        unsigned char _con_ch_buf[5];
        unsigned short _ch_buf_used;
        void *_initaddr; void *_initarg;
        void *_pxcptacttab;
        void *_tpxcptinfoptrs;
        int _tfpecode;
        void *ptmbcinfo; void *ptlocinfo;
        int _ownlocale;
        unsigned long _NLG_dwCode;
        void *_terminate; void *_unexpected;
        _se_translator_function _translator;
    };
    if (p[0] == 0x48) /* sub RSP, 0x28 */ { p += 4; }  // x64 only
    if (p[0] == 0xE8) /* call _getpid */ { ++p; }  // must be true
    void const *_getptd = p + *(long *)p + sizeof(long);
    return ((struct _tiddata *(__cdecl *)(void))_getptd)()->_translator;
}
Run Code Online (Sandbox Code Playgroud)

  • 这种hacky方式几乎让我心脏病发作.新方法更好,尽管在两个调用_set_se_translator :)之间可能会从另一个线程抛出异常的可能性范围内:) (2认同)