I want to serialize a function and send it to a different process running the same code (dynamic library). My original approach was to use the library cereal and std::function but the type is not supported and there are plenty reasons why.
Now I think about using lambda's converted to function pointers instead but I'm not quite sure if my understanding of their behavior is correct. With the following code, what does the function pointer point to? If it's a static function, I'd assume that I can move the pointer safely to the other process and call it from there.
#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();
}
Is this safe? If not, how could I achieve the same goal? I could fall back to plain old static functions and skip the lambda but I like the organization the lambda's bring to the use case I have in mind.
UPDATE
What might happen when I use templates to add the function as a template argument and then serialize the type.
#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();
}
In godbolt, execute() now calls the function via symbol, and not via function address. (As far as I understand)
The binary value of a pointer in one processes address space is random bits in another processes address space.
Dynamic libraries are often loaded at literally random addresses (called address space randomization), and even when they are not they are loaded at dynamic addresses (which may by chance be the same address, until they are not because there was another library loaded there first).
Static functions are no better than lambdas.
You need an explicit table of functions guaranteed to be in the same order in both processes, and pass an index into that table.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With