仅在运行时给出签名时的函数指针调用

时间:2013-10-23 01:25:57

标签: c++ c++11 function-pointers

考虑以下情况:

您将获得指向函数的指针作为原始指针

void * function_pointer;

并且要传递给函数的参数可用作联合类型的向量。

union Types {
  void   *ptr;
  float  *ptr_float;
  double *ptr_double;
  float  fl;
  int    in;
  double db;
  bool   bl;
};

std::vector<Types> arguments;

因此,函数的签名仅在程序状态下可用(与编译时相同)

进行此调用的推荐方式(C ++ 11)是什么?

可以将参数向量改为这样:

std::vector< std::pair<int,Types> > arguments;

其中第一个元素将清楚地标识参数的类型。

从技术上讲,签名仅以第二种形式给出。因为只有第一种形式你才能分辨出签名是什么样的。

4 个答案:

答案 0 :(得分:2)

在标准C中,您必须知道函数的签名(在编译时)才能调用它。使用声明了错误签名的函数指针调用具有一个签名的函数将导致未定义的行为。

有些库使用依赖于系统的程序集在运行时构造函数调用,如libffi。

答案 1 :(得分:1)

你能不能将联盟本身传递给函数并让它处理它想要的东西?这样所有的签名都是一样的。如果参数在上下文中不清楚,甚至可能传递两个参数,一个说一下联合数据是什么。

最后,如果你必须调用一个你无法改变签名的函数,我觉得唯一的办法是使用switch,在调用之前将指针转换为正确的签名。

答案 2 :(得分:1)

现有的库可以执行您所描述的内容,例如C / Invoke:

http://www.nongnu.org/cinvoke/

答案 3 :(得分:0)

我无法找到一种方法来“绑定”指向std::function对象的指针。也许你可能会想到这一点或其他人......但这就像我猜的那样好......它可能是但是可以在汇编/内联汇编中完成。

#include <functional>
#include <iostream>
#include <vector>

void Meh(int X, int Y)
{
    std::cout<<"Meh Arguments-> X: "<<X<<" Y: "<<Y<<"\n";
}

void Foo(std::string T)
{
    std::cout<<"Foo Arguments-> "<<T<<"\n";
}

void FuncAddr(int Args)
{
    std::cout<<"FuncAddr Arguments-> "<<Args<<"\n";
}

typedef void (*FuncPtr)(int);

int main()
{
    void* Ptr = (void*)&FuncAddr;
    std::vector<std::function<void()>> functions;

    functions.push_back(std::bind(Meh, 1, 2));
    functions.push_back(std::bind(Foo, "Hey"));
    functions.push_back(std::bind((FuncPtr)Ptr, 200));  //Perhaps there is a way to "bind" the Pointer without the cast.. Not sure how though..

    for (auto it = functions.begin(); it != functions.end(); ++it)
    {
        (*it)();
        std::cout<<"\n";
    }
}