将参数推送到调用堆栈的可移植方法(C ++)

时间:2018-05-06 23:03:04

标签: c++ parameters callstack

我正在编写一种小型脚本语言。

我正在寻找一种可移植的C ++方法将参数推送到调用堆栈,以便我的函数能够正常读取它们。

这可能吗?它必须在Visual Studio,XCode和Android Studio中编译 - 最好使用嵌入在C ++中的asm(不能选择外部汇编程序文件)

3 个答案:

答案 0 :(得分:1)

没有便携式的方法(我知道),因为#34;调用堆栈"不是便携式的东西。一台机器可能有不同的调用堆栈实现,然后另一台机器,例如PIC18器件具有单独的调用堆栈和变量堆栈,而x86共享使用相同的堆栈用于函数和变量并返回值(用非常简单的话来说......)。
最好的方法是为每个需要支持的架构和编译器创建一个单独的解决方案(宏或函数),然后使用预处理器条件结构来区分它们。使用gcc编译器时,您可以使用asm keyword,在x86架构上运行时,可以使用push instruction将数据推送到堆栈。
然后(半)可移植方式是提供一个API,在架构和编译器之间实现更改,如:

// for gcc and clang compiler for x86 architecture
#if defined(__GNUC__) && defined(__i386__)
#define PUSH_VALUE_ONTO_THE_CALL_STACK(val)  do{ \
/* this will break your code, dont use this */ \
int __v = (val); \
__asm__("push %0" : "r" (__v)); \
} while(0)
// for  Visual Studio compiler x86 architecture
#elif defined(_MSC_VER) && defined(__i386__)
#define PUSH_VALUE_ONTO_THE_CALL_STACK(val)  do{ \
/* this will break your code, dont use this */ \
__asm mov eax, val; \
__asm push eax; \
} while(0)
// add more
#elif defined(__PREDEFINED_MACRO_FOR_COMPILER) && defined(__PREDEFINED_MACRO_FOR_ARCHITECTURE)
#define PUSH_VALUE_ONTO_THE_CALL_STACK(val) /* implementation */
// when implementation is missing, issue a error
#else
#error Implementation PUSH_VALUE_ONTO_THE_CALL_STACK not found for Your architecture and compiler.
#endif

int main(void) {
      // identical usage/api between compilers and architectures
      PUSH_VALUE_ONTO_THE_CALL_STACK(5);
      return 0;
 }

希望能让你走上正轨 另外:XCode只是IDE的名称,我认为XCode默认使用clang。 Android Studio may use clang or gcc

答案 1 :(得分:1)

AFAIK,没有可移植的方式。

此外,嵌入在C ++中的asm不可移植,MS Visual Studio在编译Win64时不支持它。

解决此问题的一种方法是在C或C ++之上发明一些ABI,适合您的特定用例和脚本语言。这可以通过便携方式完成,无需组装。

了解MS如何使用他们的VBScript,IDispatch和VARIANT数据类型。

我不是说你必须坚持使用OLE自动化ABI,这只是一个例子。例如。如果只将几个浮点值传递给函数,则可以执行以下操作: int Invoke(IDFunc func, int argc, const float* argv),让您的脚本运行时将函数名解析为IDFunc标识符,填充参数数组,并调用Invoke函数。然后在互操作的C ++端调用正确的函数。您不再需要手动推送参数,只需要调度函数调用,并且有很多方法可以实现,宏,模板,代码生成或它们的某种组合。

P.S。对于MS OLE,IDFunc数据类型是int16,但是你可以使它成为指向某个东西的指针,可能有助于实现。

答案 2 :(得分:0)

如果你有C ++ 17,便携式方式是std::apply

Here’s a demo,请参阅Engine \ Function.hpp源文件。