5

考虑以下情况:

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

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

4 回答 4

2

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

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

于 2013-10-24T03:09:33.807 回答
1

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

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

于 2013-10-23T01:29:02.973 回答
1

现有的库可以执行您描述的操作,例如 C/Invoke:

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

于 2013-10-24T02:56:29.677 回答
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";
    }
}
于 2013-10-24T01:29:04.733 回答