【发布时间】:2019-07-18 13:36:55
【问题描述】:
我想序列化一个函数并将其发送到运行相同代码(动态库)的不同进程。我最初的方法是使用图书馆谷物和std::function,但不支持该类型并且有很多原因。
现在我考虑使用转换为函数指针的 lambda,但我不太确定我对它们的行为的理解是否正确。使用下面的代码,函数指针指向什么?如果它是一个静态函数,我会假设我可以将指针安全地移动到另一个进程并从那里调用它。
#include <iostream>
// Nice name for function type
using Foo = int(*)();
int main()
{
auto func = []() -> int
{
return 1;
};
// convert lambda to function pointer w/o captures
Foo fo = func;
// move (serialized) 'Foo fo' to different process
// ...
// calling function pointer in different process
std::cout << fo();
}
这样安全吗?如果没有,我怎么能达到同样的目标?我可以退回到普通的旧静态函数并跳过 lambda,但我喜欢 lambda 为我想到的用例带来的组织。
更新
当我使用模板将函数添加为模板参数然后序列化类型时可能会发生什么。
#include <iostream>
template<void(*F)()>
class SerializableObj
{
public:
void execute()
{
F();
}
};
void foo()
{
std::cout << "HI!";
}
int main()
{
// calling function pointer in different process
SerializableObj<foo> obj;
// serialize and move obj
// ...
// in other thread / process
obj.execute();
}
在 Godbolt 中,execute() 现在通过符号调用函数,而不是通过函数地址。 (据我所知)
【问题讨论】:
-
至少,我无法想象它是如何便携的。也许它适用于远程进程是相同二进制文件的特定平台。该标准没有提及有关多进程或应用程序通信的多个实例的任何内容,因此我怀疑其中是否存在有关其工作原理的任何信息。但是我不清楚您是否打算识别两个二进制文件都具有的函数,或者您是否打算以某种方式序列化整个函数并将其推送(正文和全部)。
-
我有两个进程运行相同的二进制文件(动态库),所以相同的代码库。我想在第二个进程的一个进程中移动我定义的函数(通过 lambda)并在那里调用它。
-
两个进程是什么意思?您启动程序两次并发送数据?或者您是否在同一个(单个)程序中启动两个线程?另外,你想通过发送函数来实现什么?看起来很复杂,很不安全……或许还有别的办法……
标签: c++ serialization lambda function-pointers