我正在一个项目中创建探查器,并且希望使其易于集成到我的项目中。我正在使用带有/ GH / Gh编译器标志的penter和pexit,以便每次调用或返回函数时都调用这些函数。现在,基本上,我在项目中要做的就是在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;                                              \
}                                                        \


谢谢你的帮助!

最佳答案

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

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

extern“ C”内联void __declspec(裸)_cdecl _pexit(无效)
{
  _asm pushad;
  Profiler :: GetInstance()。Exit();
  _asm popad;
  _asm ret;
}

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

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

关于c++ - 用于penter和pexit的Visual Studio宏,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23071932/

10-10 00:40