gpt4 book ai didi

c++ - 使用 Cereal 序列化 Lambda 函数

转载 作者:太空狗 更新时间:2023-10-29 21:09:48 24 4
gpt4 key购买 nike

我想序列化一个函数并将它发送到运行相同代码(动态库)的不同进程。我最初的方法是使用库 cereal 和 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++ - 使用 Cereal 序列化 Lambda 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57095837/

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