【问题标题】:Calling a C++ function using function pointer使用函数指针调用 C++ 函数
【发布时间】:2013-07-02 07:29:29
【问题描述】:

我有一个函数,它接收一个函数指针和一个 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 吗?

任何帮助将不胜感激。

【问题讨论】:

  • 你的意思是void CallFunction( void (*pFuncion)(void), std::string xmlFuncionDef) 吗?
  • 您询问“如何调用该函数”。但是第一部分已经不清楚了:你如何接收指向那个函数的指针? void * pFuncion 是 void 类型的指针,这不是指向函数的指针。
  • 如果您的代码应该在特定架构上运行,那么您可以使用内联汇编并将参数压入堆栈,然后调用该函数。但是你的函数负责以正确的顺序从堆栈中取出参数。无论如何,您的问题没有明确定义。更具体一些并展示一些示例。
  • 似乎您正在尝试发明 COM、SOAP Web 服务或类似的架构。这是一项相当大的任务。

标签: c++ c mfc


【解决方案1】:

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

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

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

void (*pFunc)(void*) 

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

【讨论】:

    【解决方案2】:

    您最好的方法是让注册函数的代码位在其参数和返回类型上成为模板。然后,您可以将其拆开并返回一个 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-04-16
      • 1970-01-01
      • 1970-01-01
      • 2017-11-24
      • 1970-01-01
      • 1970-01-01
      • 2016-01-01
      相关资源
      最近更新 更多