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

Posted

技术标签:

【中文标题】使用函数指针调用 C++ 函数【英文标题】:Calling a C++ function using function pointer 【发布时间】: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 服务或类似的架构。这是一项相当大的任务。 【参考方案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

【讨论】:

以上是关于使用函数指针调用 C++ 函数的主要内容,如果未能解决你的问题,请参考以下文章

c#调用c++的DLL,接口函数参数有函数指针,在线等解决办法

c++指针函数的使用——回调函数

c++类的成员函数指针如何转为普通指针

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

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

C++|详解类成员指针:数据成员指针和成员函数指针及应用场合