c++中动态创建函数的调用约定
Calling convention for dynamically created function in (Visual) C++
我使用以下类型在运行时创建一个新函数:
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).aspx和http://en.wikipedia.org/wiki/X86_calling_conventions#cdecl将参数放在堆栈上,但是当我查看生成的程序集时,参数被移动到EAX寄存器。
我想绝对确定参数是如何准备的。所以我忽略了一些关于cdecl
或Visual c++优化调用,如果是这样,我如何确保它不会发生?
向Lasse Espeholt致以最诚挚的问候
EAX
寄存器用于该函数的返回值。您在注释中声明您正在使用/Gd
进行编译,因此该函数将使用__cdecl
。尽管如此,在我看来,用显式的__cdecl
标记函数类型pfunc
的声明是有意义的,这样就不会有混淆和不匹配的余地。
至少在Linux上,您可能希望使用libffi(外部函数接口),它甚至被移植到其他系统(包括Windows)。
如果你想在运行时生成机器码,考虑使用GNU闪电,DotGnu的libjit, LLVM。你也可以生成C代码到foo.c
,通过gcc -fPIC -shared foo.c -o foo.so
命令和dlopen("./foo.so", RTLD_GLOBAL)
(和Windows有同等的能力)来编译它
相关文章:
- 为什么在 x64 中忽略__stdcall调用约定?
- 窗口调用约定
- 我应该提到纯虚函数中的调用约定吗?
- 如何使用gcc指定stdcall调用约定
- Clang:x86 FPU调用约定
- 该标准是否说明了例外和不同调用约定的共存
- Clang++的InterlockedExchange的32位调用约定错误,但MSVC可以
- std::sort & comp - 调用约定?
- 如何为类 /块 /范围选择C 调用约定
- DLL 的"good"调用约定是什么?
- 结构中重载运算符的调用约定
- 'ShowSUM':__declspec(dllexport)不能应用于具有__clrcall调用约定的函数
- x86-64 调用约定中的返回值
- 内联功能和调用约定
- 正在直接显示筛选器中调用约定
- 何时使用`__fastcall`调用约定
- 为C++结构定义显式析构函数如何影响调用约定
- 由于使用 MFC 时"__cdecl"和"__thiscall"调用约定不匹配而导致的链接器错误?
- Microsoft Visual C++是否未使用带有浮点的C/C++调用约定
- 在Visual Studio中调用约定