用于 penter 和 pexit 的 Visual Studio 宏

Posted

技术标签:

【中文标题】用于 penter 和 pexit 的 Visual Studio 宏【英文标题】:Visual Studio macro for penter and pexit 【发布时间】:2014-04-14 23:08:07 【问题描述】:

我正在一个项目中创建一个分析器,我想让它轻松集成到我的项目中。我将 penter 和 pexit 与 /GH /Gh 编译器标志一起使用,因此每次调用或返回函数时都会调用这些函数。现在,基本上我在我的项目中所要做的就是在全局范围内的任何地方复制 penter 和 pexit 函数,并且可以工作,但我想制作一个宏,所以它基本上只是将函数插入其中。我在我的 Profiler.h 文件并将其包含在我的其他项目中。我得到的错误是

error C2598: linkage specification must be at global scope
error C2601: '_pexit' : local function definitions are illegal
error C1075: end of file found before the left brace '' at 'path/main.cpp' was matched

请注意,“path/main.cpp”是我的项目(非分析器项目)的一条长路径,而 main 是我“调用”宏的地方

这是我的宏,我一定是理解错了。我想它只是在它被“调用”的地方插入函数

#define PENTER                                           \
extern "C" void __declspec(naked) _cdecl _penter(void)   \
                                                        \
  _asm push ebp;                                         \
  _asm mov ebp, esp;                                     \
  _asm pushad;                                           \
  Profiler::GetInstance().Enter();                       \
  _asm popad;                                            \
  _asm mov esp, ebp;                                     \
  _asm pop ebp;                                          \
  _asm ret;                                              \
                                                        \


#define PEXIT                                            \
extern "C" void __declspec(naked) _cdecl _pexit(void)    \
                                                        \
  _asm push ebp;                                         \
  _asm mov ebp, esp;                                     \
  _asm pushad;                                           \
  Profiler::GetInstance().Exit();                        \
  _asm popad;                                            \
  _asm mov esp, ebp;                                     \
  _asm pop ebp;                                          \
  _asm ret;                                              \
                                                        \

感谢您的帮助!

【问题讨论】:

查看之前的代码,包括在此之前获得#included 的所有.h 文件。缺少 。 我将宏复制到它们被调用的同一个地方,它可以正常工作,没有问题,没有更改任何其他内容 【参考方案1】:

您很可能在 profiler.h 之前的某个位置缺少 。

我会使用inline 函数而不是多行宏。

extern "C" inline void __declspec(naked) _cdecl _pexit(void) _asm pushad; Profiler::GetInstance().Exit(); _asm 流行音乐; _asm ret;

(这样,实际上可以在调试时单步执行该函数 - 至少在未内联的调试模式下)。

我还删除了完全不必要的 esp/ebp 保存和恢复 - PUSHAD 将为您保存所有寄存器(甚至 esp)[从技术上讲,您只需要保存/恢复暂存寄存器、EAX、ECX 和EDX,因为所有其他寄存器必须由您调用的函数保存。

【讨论】:

【参考方案2】:

您可以尝试micro-profiler 来完成任务。或者从这里收集它的来源:hooks.asm 它的好处是它也适用于 x64(您不能在 x64 cpp 中注入汇编指令)。

【讨论】:

以上是关于用于 penter 和 pexit 的 Visual Studio 宏的主要内容,如果未能解决你的问题,请参考以下文章

Visual Studio 2013 /GH /Gh _penter/_pexit 64bit 如何保存寄存器?

C++ - 从结束地址获取函数的起始地址/获取函数的大小

visua studio 自定义路径宏

win10 64位 python3.6 django1.11 MysqlDB No module named 'MySQLdb' 安装MysqlDB报错 Microsoft Visua

如何在 Visual Studio Code 中设置用于调试 PowerShell 的环境变量?

OpenCC的编译与多语言使用