gpt4 book ai didi

c++ - 在 C++ 中调用任意函数

转载 作者:行者123 更新时间:2023-11-30 01:10:16 24 4
gpt4 key购买 nike

我正在用 C++ 开发一个非常小的 RPC 库。我想像这样注册 RPC 函数:

void foo(int a, int b) {
std::cout << "foo - a: " << a << ", b: " << b << std::endl;
}

myCoolRpcServer->registerFnc("foo", foo(int,int))

客户端请求将作为函数名和参数数组到达。服务器会检查自己是否注册了相应的函数,如果是,则执行该函数。

MyCoolRpcServer::handleRequest(string fnc, vector<FncArg> args)
{
// Check if we have the function requested by the client:
if (!this->hasFunction(fnc)) {
throw ...
}

if (!this->function(fnc).argCnt != args.count()) {
throw ...
}

// I think this is the hardest part - call an arbitrary function:
this->function(fnc)->exec(args); // Calls the function foo()
}

我的问题是如何存储函数引用(包括参数类型)以及如何再次调用它。我知道当我调用 SLOT(...) 宏时,在 Qt 中必须使用类似的东西,但是在这么大的库中找到它是相当棘手的...

感谢您的建议。

克拉西克

最佳答案

您可能会使用 std::function但是您的主要问题是注册函数的签名(即参数的数量和类型,结果类型)是什么,以及如何在编译时和运行时都知道它(以及如何调用任意函数,运行时已知,签名)。请注意,C++ 通常是 erasing types (它们在运行时被“遗忘”)。

请注意函数的签名在 C 和 C++(对于编译器)中非常重要,因为 calling conventionsABI可能需要不同的机器代码来调用它们。

你可以决定你有一些通用值类型(可能是 future 的 std::experimental::any )。或者(更简单,但更不通用)您可以定义一些抽象父类(super class) MyValue (它可能是来自 Qt 的 QVariant,或者受其启发)并且只处理映射单个 std::vector<MyValue> 的函数(概念上代表您的 RPC 的参数)到 MyValue结果。那么你将只注册 lambda-expressionsstd::function<MyValue(std::vector<MyValue>))> 兼容并要求他们在运行时检查数量和类型。

或者,您可以决定限制自己使用几个签名,例如只接受不超过 4 个参数的函数,每个参数要么是 std::stringint (因此您将一一处理 31 个不同的签名)。

您还有与 serialization 相关的问题共享一些公共(public)指针(或子值)的任意值。查看libs11n .

您还可以使用一些机制来注册签名本身。您可以利用现有的元数据机制(例如 Qt 元对象协议(protocol))。您可以对类型和签名进行一些文本描述,然后编写一些 C++ 代码生成器来处理它们。

您可能会查看 libffi .它可能与调用具有任意签名的任意原始函数有关。

如果足够通用,您的库就不会很小。你可能会限制自己,例如JSON值和表示。参见 JSONRPC .

你可能有一个 metaprogramming方法,例如给出注册函数的签名(以某种定义的格式),在运行时生成(初始化)plugin 的 C++ 代码为他们的胶水代码,编译和dynamically load该插件(例如在 Linux 上使用 dlopen(3))。

另请查看 CORBA & ONCRPC & Boost.RPC .

附言。我假设你的 C++ 至少是 C++11。顺便说一句,如果您想要一个通用的解决方案,您就低估了目标的难度。您可能会为此花费数月或数年。

关于c++ - 在 C++ 中调用任意函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38351465/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com