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

最好的方法是使注册函数的代码位在其参数和返回类型上成为模板。然后,您可以将其拆开并返回一个 lambda,该 lambda 知道如何解析 XML 并调用该函数。真正的 hacky 概念证明 [它不处理 varargs(硬编码为 2),使用字符串而不是 xml,假设类型是默认可构造的,不处理 refs 或移动,并且给读者留下了很多练习] 是:

#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 回答
0

据我所知,函数指针不能有灵活的参数——你必须准确地告诉函数将接收什么样的参数。在您的示例中:

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

当然,您可以使用 void* 作为唯一参数,然后在内部处理这种可变性:

void (*pFunc)(void*) 

但是,我相信这将是一个混乱的邀请。

于 2013-07-02T07:44:14.380 回答