使用函数指针调用C ++函数

时间:2013-07-02 07:29:30

标签: c++ c mfc

我有一个接收函数指针的函数和一个 XML 字符串,该字符串具有函数的定义和每个说法的参数:

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

}

在上面的函数中,xmlFunctionDef包含pFunction指向的函数的定义。例如,number参数,每个参数的类型以及参数:

<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吗?

任何帮助都将受到高度赞赏。

2 个答案:

答案 0 :(得分:0)

据我所知,函数指针不能有灵活的参数 - 你必须确切地告诉函数将接收哪种参数。在您的示例中:

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

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

void (*pFunc)(void*) 

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

答案 1 :(得分:0)

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

#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