c++ - (Visual) C++ 中动态创建函数的调用约定

标签 c++ c visual-c++ x86

我使用以下类型在运行时创建一个新函数:

typedef int (*pfunc)(int);

union funcptr {
  pfunc x;
  byte* y;
};

这使我能够在 y 中编写指令,然后像这样调用函数:

byte* p = (byte*)VirtualAllocEx(GetCurrentProcess(), 0, 1<<16, MEM_COMMIT, PAGE_EXECUTE_READWRITE );

// Write some instructions to p

funcptr func;
func.y = p;

int ret = func.x(arg1); // Call the generated function

了解 C++ 如何准备参数(调用约定)至关重要,因此我查看了项目属性 (Visual C++),我可以看到它使用 __cdecl。它应该根据以下参数将参数放在堆栈上:http://msdn.microsoft.com/en-us/library/aa271989(v=vs.60).aspxhttp://en.wikipedia.org/wiki/X86_calling_conventions#cdecl但是当我查看生成的程序集时,参数被移动到 EAX 寄存器。

我想绝对确定参数是如何准备的。那么我是不是忽略了一些关于 cdecl 的事情,或者 Visual C++ 是否优化了调用,如果是这样,我如何确保它不会发生?

最好的问候,Lasse Espeholt

最佳答案

EAX 寄存器是 used for the return value of the function .您在评论中声明您正在使用 /Gd 进行编译所以该函数将使用 __cdecl .尽管如此,在我看来,用显式 __cdecl 标记函数类型 pfunc 的声明是有意义的,这样就不会出现混淆和不匹配的情况.

当然,没有什么可以阻止您使用您的编译器支持的其他调用约定之一。最重要的一点是,无论您选择哪种调用约定,都应该明确指定函数指针的调用约定,因为编译器只负责接口(interface)的一半。

关于c++ - (Visual) C++ 中动态创建函数的调用约定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8279715/

相关文章:

c++ - reinterpret_cast - 整数、枚举、指针或成员指针类型的表达式可以转换为它自己的类型

c++ - 在 crtdbg.h 导致冲突时覆盖 C++ 中的新运算符

c++ - 使用反引号时程序不输出

c++ - 是否可以在不对抽象的父类中的函数使用 virtual 关键字的情况下覆盖 C++ 子类中的函数?

c++ - 如何让 MSVC 将未初始化的数据放入 .bss?

c++ - 传递包含空格和引号的参数字符串

c++ - C中的GDI不绘制连续的对象

c - OpenCV 中的肤色检测

c - x86内核中的键盘IRQ

c++ - 如何使用 Visual Studio 2012 为 Windows XP 编译?