Directly serializing and deserializing into objects was and more
boilerplate heavy (since we now need two implementations even though we
only use one), and also much less flexible because we can't wrap
payloads in structs or provide optional values that way.
This is less likely to clash with names used by interfaces and it's a
bit clearer what's going on (since they are basically proxies for
constructors and destructors).
Transferring some argument pack is much easier than trying to
deserialize into an existing object when you also have to transfer more
information than just that object.
This now takes a regular overloaded function and the visiting is done in
`receive_messages()` itself. This way we can use templates to ensure
that the return type is correct. Otherwise auto will cause issues in the
future when we want to return multiple concrete types from a function
that takes a single variant. The alternative would be both receiving a
variant as a parameter and then returning another variant as a result,
but that is much less type safe.
And add separate implementations for the native plugin and the Wine
plugin host. This way we can easily allow the native host to do
callbacks without having to manage a load of lambdas.