C++;通过字符串名调用不同的函数 我对C++是比较陌生的——我在大约6年前就学会了它,但直到几个月前才真正使用它。 情况是什么: 具有许多模块的相当大的系统 期望输出: 模块(即X)“公开”通过网络调用的某些函数,并将结果发送回调用方(即Y) 调用方Y不知道关于X的任何信息,不管库公开了什么(函数名和参数) 从库中调用X中的函数必须通过从Y接收的字符串或一组字符串进行,因为也会有参数

C++;通过字符串名调用不同的函数 我对C++是比较陌生的——我在大约6年前就学会了它,但直到几个月前才真正使用它。 情况是什么: 具有许多模块的相当大的系统 期望输出: 模块(即X)“公开”通过网络调用的某些函数,并将结果发送回调用方(即Y) 调用方Y不知道关于X的任何信息,不管库公开了什么(函数名和参数) 从库中调用X中的函数必须通过从Y接收的字符串或一组字符串进行,因为也会有参数,c++,visual-studio-2010,boost,function-pointers,C++,Visual Studio 2010,Boost,Function Pointers,理想情况下,我想要的是一些尽可能通用的变量返回/参数类型,或者某种类型的擦除——因为我不知道每个模块将要公开哪些函数。我认为它是相当的乌托邦,以获得类似的运行在C++中。但希望通过预先确定可能的回报/参数类型,这是可行的。现在沟通不是问题,重要的是模块端应该做什么 问题: 用C++和Boost实现这样的事情是可能的吗?如果有人能给我一些指导——文献/教程/(伪)代码示例等等,我会非常感激。我不希望在这里有一个完整的解决方案 可能的解决办法: 对于我可以/应该使用哪些语言的“功能”,我有点不知

理想情况下,我想要的是一些尽可能通用的变量返回/参数类型,或者某种类型的擦除——因为我不知道每个模块将要公开哪些函数。我认为它是相当的乌托邦,以获得类似的运行在C++中。但希望通过预先确定可能的回报/参数类型,这是可行的。现在沟通不是问题,重要的是模块端应该做什么

问题:
    用C++和Boost实现这样的事情是可能的吗?如果有人能给我一些指导——文献/教程/(伪)代码示例等等,我会非常感激。我不希望在这里有一个完整的解决方案
可能的解决办法: 对于我可以/应该使用哪些语言的“功能”,我有点不知所措——主要是由于我在项目中的限制

我考虑过使用可变模板,发现了下面的问题,这确实有帮助,唯一的问题是可变模板在VS2010中不受支持

在网络上进行了广泛的研究之后,我得到的最接近的答案是:

情况大致相同。然而,在我看来,区别在于OP已经事先知道了他将使用的函数的返回/参数。由于我的名声不好(我刚刚加入),很遗憾,我不能在那里询问/评论任何事情

TBH我没有弄清楚如何完成所选答案的解释

使用映射是一种方法,但我必须存储包含函数指针的对象(正如问题中所回答的),但由于用户在提供的代码中可以看到,它确实有一些硬编码的东西,这是我不希望有的

进一步澄清:

    是的,我只限于使用C++和VS2010 SP1../LI>
  • 不,尽管有Boost,但我不能使用任何其他第三个库-能够使用一些反射库(如CPGF)将非常好(尽管我不能100%确定这是否是我真正需要的)
次要编辑: -脚本语言绑定(比如LUA)确实是一种方法,但我不想将其包括在项目中

我希望有人能阐明这个问题


提前感谢您的任何意见

看起来你需要一个小小的反射模块。例如,我们有一个方法信息结构,例如:

struct argument_info {
    std::string name;
    std::string type;
    std::string value;
}

struct method_info {
    std::string method_name;
    std::string return_type;
    std::list<argument_info> arguments;
}
在口译员的代码中:

void call_function(method_info mi, argument_info& t_return)
{
    /* let g_mi be a map, where key is a std::string name of the method and the 
       value is method_info struct */ 
    if(!g_mi->find(mi.method_name))
        throw MethodNotFindException

    if(g_mi[mi.method_name].arguments.size() != mi.arguments.size())
        throw InvalidArgumentsCountException;

    for(int i = 0; i < g_mi[mi.method_name].arguments.size(); i++)
    {
        if(g_mi[mi.method_name].arguments[i].type != mi.arguments[i].type)
            throw InvalidArgumentException;
    }

    t_return = module->call(mi.arguments); 
}
void call\u函数(方法信息mi、参数信息&t返回)
{
/*假设g_mi是一个映射,其中key是方法和
值为方法\u信息结构*/
如果(!g_mi->find(mi.method_name))
抛出MethodNotFindException
if(g_mi[mi.method_name].arguments.size()!=mi.arguments.size())
抛出无效辩论例外;
对于(int i=0;icall(mi.arguments);
}

<>希望对你有帮助。

听起来像是在把C++函数和类暴露给脚本语言(如Lua)时所面临的问题,所以你可以看看这些是如何实现灵感的。(例如)看起来您需要一个RPC系统。这里有很多,例如ApacheStrift。感谢你们两位的及时输入。我一定会调查的!我刚刚想起了脚本语言绑定,这些绑定并不是我想要包含在项目中的(我将编辑本文)。然而,如果没有其他办法,那么我必须看看能做些什么!您如何在Y中使用这些函数?不是调用的机制:但是Y如何知道调用一个特定的函数——谁来告诉它?没有一些外部信息,它无法知道。有脚本吗?用户输入?是否有一些代码假设
X
将有一些函数通过
Y
路由调用?@yaky是一个用户界面,因此用户将决定要调用哪个函数以及要传递的参数。UI本身将负责查询模块中的可用命令。我回答了所有问题吗?如果我误解了,请纠正我,但我需要将模块X中的函数编译成DLL?如果是这样的话,恐怕这对我没有帮助,因为我对模块没有任何控制权,只有开发人员,因此,我要提供最简单的方法。简单到“我希望这个函数从外部调用!完成其余的”。很抱歉,我误解了。您的问题很复杂,但似乎cpgf符合您的标准,还有boost::python,不知道lua如何。所以,看看里面。无论如何,谢谢你抽出时间回答!非常感谢!关于脚本语言,我会尽量不接触。我在项目中有一些限制,不允许我那么容易地放置其他库。
void call_function(method_info mi, argument_info& t_return)
{
    /* let g_mi be a map, where key is a std::string name of the method and the 
       value is method_info struct */ 
    if(!g_mi->find(mi.method_name))
        throw MethodNotFindException

    if(g_mi[mi.method_name].arguments.size() != mi.arguments.size())
        throw InvalidArgumentsCountException;

    for(int i = 0; i < g_mi[mi.method_name].arguments.size(); i++)
    {
        if(g_mi[mi.method_name].arguments[i].type != mi.arguments[i].type)
            throw InvalidArgumentException;
    }

    t_return = module->call(mi.arguments); 
}