_set_se_translator 的“get”等价物?
Posted
技术标签:
【中文标题】_set_se_translator 的“get”等价物?【英文标题】:The 'get' equivalent of _set_se_translator? 【发布时间】:2012-08-14 01:27:09 【问题描述】:我需要使用当前翻译器手动翻译结构化异常。
我如何“获取”某人通过_set_se_translator
设置的值?
【问题讨论】:
【参考方案1】:更好的(新)方式
一开始我没有意识到这一点,但 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;
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;
【讨论】:
这种骇人听闻的方式差点让我心脏病发作。新方法更好,尽管有可能在两次调用 _set_se_translator 之间从另一个线程抛出异常:) @Luke:哈哈。如何从另一个线程抛出异常? Doh,没有看到关于每个线程维护处理程序的部分。以上是关于_set_se_translator 的“get”等价物?的主要内容,如果未能解决你的问题,请参考以下文章
PHPUnit:模拟__get()导致“__ get()必须正好接受1个参数......”
php __set()和__get()的具体用法,举例说明,谢~
php __CLASS__get_class()与get_called_class()的区别