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;

ペアの最初の要素は、引数の型を明確に識別します。

技術的には、署名は 2 番目の形式でのみ与えられます。最初のフォームだけでは、署名がどのようなものかわかりません。

4

4 に答える 4

2

標準 C では、関数を呼び出すには、(コンパイル時に) 関数のシグネチャを知っている必要があります。間違ったシグネチャで宣言された関数ポインタを使用して 1 つのシグネチャの関数を呼び出すと、未定義の動作が発生します。

libffi のように、システム依存のアセンブリを使用して実行時に関数呼び出しを構築するライブラリがあります。

于 2013-10-24T03:09:33.807 に答える
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 に答える