2017-01-24 10 views
0

私はマップboost::functionsを試しています。だから私は入力と出力のパラメータで、文字列名でそれらを呼び出すことができます。変数をvoidポインタ、またはC++のvoidポインタ参照に送ります

例:私は、入力と出力変数を作成し、処理するMyFuncs::CallFunc()に自分のポインタを送りたい

MyFuncs::CallFunc("MyClass::TestFunc", void* input, void* output); 

私はそれがintに値だ関数に(void* input)ポインタを送信し、抽出することができ、文字列など

私はそれが値を受け取るために自分のスペースだ割り当て(void* output)を送信することはできません。呼び出された関数の内部にnew type(var)を作成する必要があります。そうしないと、関数は戻ってもスコープから外れます。

MyFuncs.h

//MyFuncs.h 
#include <boost/function.hpp> 
#include <boost/bind.hpp> 
#include <map> 

class MyFuncs 
{ 
public: 

    static std::map<std::string, boost::function<void (void*, void*&)> > myfuncs; 

    template<class T> 
    static void RegisterFunc(const std::string& name, void (T::*func) (void*, void*&), T* instance) 
    { 
     myfuncs[name] = boost::bind(func, instance, _1, _2); 
    } 

    static void CallFunc(const std::string& name, void* input, void*& output) 
    { 
     myfuncs[name](input, output); 
    } 
}; 

std::map<std::string, boost::function<void (void*, void*&)> > MyFuncs::myfuncs; 


MyClass.h

//MyClass.h 
#include "MyFuncs.h" 

class MyClass 
{ 
public: 
    MyClass() 
    { 
     MyFuncs::RegisterFunc("MyClass::GetNumber", &MyClass::GetNumber, this); 
     MyFuncs::RegisterFunc("MyClass::GetString", &MyClass::GetString, this); 
     MyFuncs::RegisterFunc("MyClass::EditNumber", &MyClass::EditNumber, this); 
     MyFuncs::RegisterFunc("MyClass::EditString", &MyClass::EditString, this); 
    } 

    void GetNumber(void* input, void*& output) 
    { 
     int var = 1234; 
     output = static_cast<void*>(new int(var));    //WORKS, var eats memory 
     //output = static_cast<void*>(&var);     //ERROR, var goes out of scope 
    } 

    void GetString(void* input, void*& output) 
    { 
     std::string var = "Get test"; 
     output = static_cast<void*>(new std::string(var));  //WORKS, var eats memory 
     //output = static_cast<void*>(&var);     //ERROR, var goes out of scope 
    } 

    void EditNumber(void* input, void*& output) 
    { 
     int var = *static_cast<int*>(input);     //WORKS, var gets 4321 OK 
     output = static_cast<void*>(new int(var));    //WORKS, var eats memory 
     //output = static_cast<void*>(&var);     //ERROR, var goes out of scope 
    } 

    void EditString(void* input, void*& output) 
    { 
     std::string var = *static_cast<std::string*>(input); //WORKS, var gets "Edit test" OK 
     output = static_cast<void*>(new std::string(var));  //WORKS, var eats memory 
     //output = static_cast<void*>(&var);     //ERROR, var goes out of scope 
    } 
}; 


MyApp.cpp

//MyApp.cpp 
#include "MyClass.h" 

void main() 
{ 
    MyClass myclass; 

    void* in; 
    void* out; 

    MyFuncs::CallFunc("MyClass::GetNumber", NULL, out); //atempting to fill the variable 
    int getNumOut = *static_cast<int*>(out); 
    printf("MyClass::GetNumber = %d \n", getNumOut); 

    MyFuncs::CallFunc("MyClass::GetString", NULL, out); //atempting to fill the variable 
    std::string getStrOut = *static_cast<std::string*>(out); 
    printf("MyClass::GetString = %s \n", getStrOut.c_str()); 

    int editNum = 4321; 
    in = static_cast<void*>(&editNum); 
    MyFuncs::CallFunc("MyClass::EditNumber", in, out); //atempting to fill the variable 
    int editNumOut = *static_cast<int*>(out); 
    printf("MyClass::EditNumber = %d \n", editNumOut); 

    std::string editStr = "Edit test"; 
    in = static_cast<void*>(&editStr); 
    MyFuncs::CallFunc("MyClass::EditString", in, out); //atempting to fill the variable 
    std::string editStrOut = *static_cast<std::string*>(out); 
    printf("MyClass::EditString = %s \n", editStrOut.c_str()); 

    getchar(); //wait for close 
} 
+2

、あなたは[ 'のstd :: any'](HTTPの使用を検討したいと思うでしょう/en.cppreference.com/w/cpp/utility/any)では 'void * 'ではなく。あなたはC++ 17が正式にロールアウトする前にBoostバージョンを使うことができます – WhiZTiM

+0

@WhiZTiM今すぐ調査していただきありがとうございます。 – aquawicket

+0

Opps。私はまだいくつかのクロスプラットフォームの特質のためにC++ 98です。なぜ私はまだここでブーストを使用しているのですか? std :: anyは私にはまだ利用できません。 – aquawicket

答えて

0

SOLUTION
、私は純粋なC++を使用することができました。

*(int*)output = var;*(std::string*)output = var;と思われます。


MyFuncs.h

#include <boost/function.hpp> 
#include <boost/bind.hpp> 
#include <map> 

class MyFuncs 
{ 
public: 

    //A list of function names linked to boost::functions. 
    static std::map<std::string, boost::function<void (void*, void*)> > myfuncs; 


    //Register a class function by name.  MyFuncs::RegisterFunc("MyClass::Test", &MyClass::Test, instance); 
    template<class T> 
    static void RegisterFunc(const std::string& name, void (T::*func) (void*, void*), T* instance) 
    { 
     myfuncs[name] = boost::bind(func, instance, _1, _2); 
    } 


    //Call functions by name, with input and output.  MyFunct::CallFunc("MyClass::Test", input, output); 
    static void CallFunc(const std::string& name, void* input, void* output) 
    { 
     myfuncs[name](input, output); 
    } 
}; 

std::map<std::string, boost::function<void (void*, void*)> > MyFuncs::myfuncs; 



MyClassの。/:H C++ 17では

#include "MyFuncs.h" 

class MyClass 
{ 
public: 
    MyClass() 
    { 
     MyFuncs::RegisterFunc("MyClass::GetNumber", &MyClass::GetNumber, this); 
     MyFuncs::RegisterFunc("MyClass::GetString", &MyClass::GetString, this); 
     MyFuncs::RegisterFunc("MyClass::EditNumber", &MyClass::EditNumber, this); 
     MyFuncs::RegisterFunc("MyClass::EditString", &MyClass::EditString, this); 
    } 

    void GetNumber(void* input, void* output) 
    { 
     int var = 1234; 
     *(int*)output = var; 
    } 

    void GetString(void* input, void* output) 
    { 
     std::string var = "Get test"; 
     *(std::string*)output = var; 
    } 

    void EditNumber(void* input, void* output) 
    { 
     int in = *(int*)input; //4321 
     int out = in - 4320; //result is 1; 
     *(int*)output = out; 
    } 

    void EditString(void* input, void* output) 
    { 
     std::string in = *(std::string*)input; //"Edit Test" 
     std::string out = in += " (edited)"; //result is "Edit test (edited)" 
     *(std::string*)output = out; 
    } 
}; 



MyApp.cpp

#include "MyClass.h" 

void main() 
{ 
    MyClass myclass; 

    int getNum; 
    MyFuncs::CallFunc("MyClass::GetNumber", NULL, &getNum); 
    printf("MyClass::GetNumber = %d \n", getNum); 

    std::string getStr; 
    MyFuncs::CallFunc("MyClass::GetString", NULL, &getStr); 
    printf("MyClass::GetString = %s \n", getStr.c_str()); 

    int editNumIn = 4321; 
    int editNumOut; 
    MyFuncs::CallFunc("MyClass::EditNumber", &editNumIn, &editNumOut); 
    printf("MyClass::EditNumber = %d \n", editNumOut); 

    std::string editStrIn = "Edit test"; 
    std::string editStrOut; 
    MyFuncs::CallFunc("MyClass::EditString", &editStrIn, &editStrOut); 
    printf("MyClass::EditString = %s \n", editStrOut.c_str()); 

    getchar(); //wait for close 
} 
1

void* outmain内で宣言されています。 outを有効にするには、寿命が少なくともmainであるものを指す必要があります。 outで返されるクラスMyClassの中にタイプintstringのデータメンバーが宣言されていないので、そのメモリを割り当てる必要があります。

はあなたがクラスMyClassにデータメンバint var;を宣言し、その後はgetNumberは次のようになりますと仮定しますstatic_castをや余分なブースト機能を使用しない

class MyClass 
{ 
    private: 
      int var; 

    public: 
    MyClass() 
    { 
     //Register function 
     var = 10; 
    } 

    void GetNumber(void* input, void*& output) 
    { 
     //int var = 1234; //<-- instead of using local "var", now use MyClass::var i.e this->var 
     output = static_cast<void*>(&(this->var)); 
    } 
}; 
+0

これはうまくいくかもしれませんが、多分、複数のスレッドに入ると、爆発するかもしれません。私はクラスの外に出力変数を作成したいと思います。 – aquawicket

+1

@aquawicket:その場合、単にint out_intを実行することができます。 – sameerkn

+0

'GetNumber(void * input、void * output){int num = 69;}このメソッドは、GetNumber(void * input、void * output); void * out =(void *)&out_int; *出力= num; } '*出力は私がそれに割り当てても違法な間接です。 – aquawicket

関連する問題