【问题标题】:Generate function pointer declaration at run-time in C++?在 C++ 中运行时生成函数指针声明?
【发布时间】:2014-05-02 15:42:39
【问题描述】:

是否可以创建/生成类似于以下的指针声明:

void (*foo)(int, float);

bool (*foo)();

char (*foo)(char, int);

但直到运行时才知道参数的类型或返回类型。

函数声明将从指定返回和参数类型(如果有)的字符串中读取,然后(如果可能)存储在 c++ 容器中。

可以在运行时(不是编译时)完成吗?必要时也可以使用C++11。

我真的怀疑这可以用像 C++ 这样的静态类型语言来完成,但如果可以做到,那么有人会使用什么方法。不需要代码(但值得赞赏)只是一些必须使用的指导。

编辑:

在测试了几个想法后,发现它不能(直接)用 C++ 实现。幸运的是,我找到了 dyncall 库,它允许我(间接地)在相当多的平台上做到这一点。

示例函数:

double sqrt(double x);

使用dyncall调用函数:

double r;
DCCallVM* vm = dcNewCallVM(4096);
dcMode(vm, DC_CALL_C_DEFAULT);
dcReset(vm);
dcArgDouble(vm, 4.2373);
r = dcCallDouble(vm, (DCpointer)&sqrt);
dcFree(vm);

字符串也可以用来声明函数的结构。

C function prototype                                dyncall signature

void f1();                                          ")v"
int f2(int, int);                                   "ii)i"
long long f3(void*);                                "p)L"
void f3(int**);                                     "p)v"
double f4(int, bool, char, double, const char*);    "iBcdZ)d"

【问题讨论】:

  • 据我所知,这是做不到的。
  • 所以你有一个字符串。您将 something 存储在以某种方式从该字符串派生的容器中(它不能是声明 - 这是一个编译时概念;您将存储一些对象)。怎么办?这个练习的最终目标是什么?
  • 为什么需要这样做?是否可以重新设计您的代码,这样您就不需要这样做了?
  • 我需要能够为需要支持简单函数的小型脚本语言生成函数指针声明,以便与 AsmJit 一起使用。 AsmJit 可以将生成的代码分配给函数指针,然后可以从 c/c++ 调用。没有什么特别的,只会使用基本的 c++ 类型。没有物体或任何类似的东西。也许是指针,但除此之外没有其他东西可以用于参数。
  • 没有。使函数接受 Variants 的容器(其中“Variant”是一个可以包含各种类型数据的对象)。

标签: c++ c++11 runtime function-declaration dyncall


【解决方案1】:

这取决于您将处理多少类型的参数。从技术上讲 - 你可以用 C++ 做所有事情,只是有时它并不像你想要的那么简单。

您可以使用委托模式

class baseDelegate(){};

template<typename retT, typename paramT>
class delegate: public baseDelegate{
    public:
    retT (*ptr)(paramtT);
};

vector<baseDelegate*> yourDelegateList;

由于您将主题标记为C++11,您还可以使用std::function可变参数模板等,以使其更容易。上面的代码只是一个例子。

【讨论】:

  • 是的,但 std::function 也需要在编译时定义 std::function。我想过使用它,然后从 std::function::target_type 成员中提取函数定义。
  • 我浏览了一下,我想我可以用 std::tuple 做到这一点。只需使用 std::make_tuple 用我的值构造一个 std::tuple ,然后使用 std::tuple_element 提取元素的类型并使用它们生成一个 std::function 。我稍后会尝试,看看它是否有效,除非其他人提供经过验证的解决方案。
  • 如果你能确保所有作为参数传递的类型要么是内置的,要么是从一个基类派生的,那么这样做会容易得多。在使用委托模式时,您必须知道返回类型和参数类型的所有可能组合,但我认为您找不到更灵活的方法。
  • 除了基本的 C++ 数据类型和指针之外,我不会使用其他任何东西,因此我认为它可能适用于元组。更不用说参数编号被锁定为 16。所以,没有超过 16 个参数和一种返回类型。我只需要构建一个类似于 std::vector 的容器,它可以容纳多种类型的数据。我将使用您的“从一个基类派生”的想法来执行此操作,并根据容器的大小简单地构造一个 std::tuple 。希望它可能真的有效:)
  • 在测试了几个想法后,事实证明你不能:(这几乎是不可能的。
【解决方案2】:

你可以这样做

void function (string &arg, …) ;

并使用 C++ 的可变参数特性。

不过,您至少需要一个固定参数。

通常,正如您所指出的,您所描述的在 C++ 中并不是一件好事。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-20
    • 2021-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多