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

问题描述 投票:0回答:4

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

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

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

c++ parameters callstack
4个回答
1
投票

据我所知,没有便携的方法。

此外,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++ 端,调用正确的函数。您不再需要手动推送参数,您只需要分派函数调用,并且有很多方法可以实现此目的,宏,模板,代码生成或它们的某种组合。

附注MS OLE 的

IDFunc
数据类型为 int16,但您可以将其改为指向某些内容的指针,这可能有助于实现。


1
投票

没有可移植的方法可以做到这一点(据我所知),因为“调用堆栈”不是可移植的东西。一台机器可能与另一台机器具有不同的调用堆栈实现,例如 PIC18 设备具有单独的调用堆栈和变量堆栈,而 x86 共享对函数和变量以及返回值使用相同的堆栈(用非常简单的话说...)。
最好的方法可能是为您需要支持的每个体系结构和编译器创建一个单独的解决方案(宏或函数),然后使用处理器条件结构来区分它们。当使用 gcc 编译器时,您可以使用 asm 关键字,当在 x86 架构上运行时,您可以使用 push 指令 将数据压入堆栈。
那么(半)可移植方式是提供一个 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 可以使用 clang 或 gcc


1
投票

如果你有 C++ 17,可移植的方式是 std::apply

这是一个演示,请参阅Engine\Function.hpp源文件。


0
投票

libffi 是 python 执行您想要的操作的工具:检查here

© www.soinside.com 2019 - 2024. All rights reserved.