0

関数ポインターと、関数の定義と引数ごとのXML文字列を受け取る関数があります。

void CallFunction( void * pFuncion, std::string xmlFuncionDef)
{

}

上記の関数内には、xmlFunctionDefが指す関数の定義が含まれていますpFunction。たとえば、数値パラメーター、各パラメーターの型、および引数:

<Function ParamCount="3" ReturnType="int">
  <Params>
    <Param type="int" DefaultValue="None" PassBy="Value"/>
    <Param type="double" DefaultValue="None" PassBy="Referenc"/>
    <Param type="char*" DefaultValue="None" PassBy="Pointer"/>
  </Params>

  <Arguments>
   <Arg Value="3" />
   <Arg Value="29.5" />
   <Arg Value="Hello World" />
  </Arguments>
</Function>

では、この関数をどのように呼び出すことができますか? これに使うべき_asmですか?

どんな助けでも大歓迎です。

4

2 に答える 2

0

私の知る限り、関数ポインターは柔軟な引数を持つことができません。関数が受け取るパラメーターの種類を正確に伝える必要があります。あなたの例では:

void (*pFunc)(int,double,char*)

もちろん、void* を唯一のパラメーターとして使用して、その可変性を内部的に処理することもできます。

void (*pFunc)(void*) 

しかし、それは混乱への招待になると思います。

于 2013-07-02T07:44:14.380 に答える
0

これを行う最善の方法は、関数を登録するコードのビットをそのパラメーターと戻り値のテンプレートにすることです。次に、これを分解して、XML を解析して関数を呼び出す方法を知っているラムダを返すことができます。本当にハックな概念の証明 [varargs を処理せず (2 にハードコードされている)、xml の代わりに文字列を使用し、型がデフォルトで構築可能であると想定し、refs や move を処理せず、読者の演習として多くを残している] は、 :

#include <string>
#include <functional>
#include <sstream>
#include <iostream>
#include <stdexcept>

template<class FIRST, class SECOND, class RETURN_TYPE>
std::function<RETURN_TYPE(std::string const&)> RegisterFunction(
    RETURN_TYPE(func)(FIRST f, SECOND s))
{
    auto copy = *func;
    return[copy](std::string const& str)->RETURN_TYPE
    {
        std::istringstream inStream(str);
        FIRST f;
        inStream >> f;
        if(inStream.fail())
        {
            throw std::runtime_error("Couldn't parse param one");
        }
        SECOND s;
        inStream >> s;
        if(inStream.fail())
        {
            throw std::runtime_error("Couldn't parse param two");
        }
        // can check if inStream is eof here for consistency
        return copy(f, s);
    };
}

std::string MyFunc(float f, std::string s)
{
    std::ostringstream os;
    os << "MyFunc called with float " << f << " and string " + s;
    return os.str();
}


int main()
{
    auto wrapper = RegisterFunction(MyFunc);

    // Now try to call it
    std::cout << wrapper("42.0 HelloWorld") << std::endl;

    // Try to call it with an invalid string
    try
    {
        std::cout << wrapper("This isn't the number you are looking for");
    }
    catch(...)
    {
        std::cout << "Failed to call function" << std::endl;
    }
}

出力:

MyFunc called with float 42 and string HelloWorld
Failed to call function
于 2013-07-02T12:43:48.087 に答える