我有一个接收函数指针的函数和一个 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
吗?
任何帮助都将受到高度赞赏。
答案 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