The framework allows calling a C++ server function from a C++ client in the same way as it is called locally.
The IPC transport (for instance, TCP/IP, HTTP(S), etc.) functions are placeholders and not implemented by the framework.
The synchronous IPC transport function sends to and receives from the server std::vector<uint8>.
In case of a transport error, this function should throw an exception.
Its declaration - std::vector<uint8> IpcSync(const std::vector<uint8>& bytes) noexcept(false)
Function declaration that is called on the server is the same as a declaration of a local function -
Ret f(Par1 par1, Par2 par2, ... ParN parN), where all parameters can be In or InOut.
Function call - Ret res = IPC_SEND_RECEIVE(f)(arg1, arg2, ...argN)(IpcSync),
where IpcSync is IPC transport function described above.
std::list<int> XYZ(const std::map<std::string, int>& in, std::vector<std::tuple<std::string, int>>& inOut);
std::vector<std::tuple<std::string, int>> inOut = { {"A", 1}, {"B", 2} };
std::list<int> res = IPC_SEND_RECEIVE(XYZ)({ {"C", 3}, {"D", 4} }, inOut)(IpcSync);
For a comparison, the local call would look like:
std::list<int> res = XYZ({ {"C", 3}, {"D", 4} }, inOut);
The asynchronous IPC transport function sends to the server std::vector<uint8>.
In case of a transport error, this function should throw an exception.
Its declaration - void IpcAsync(const std::vector<uint8>& bytes) noexcept(false)
Function declaration that is called on the server is the same as a declaration of a local function -
void f(Par1 par1, Par2 par2, ... ParN parN), where all parameters are In only.
Function call - IPC_SEND(f)(arg1, arg2, ...argN)(IpcAsync),
where IpcAsync is IPC transport function described above.
void ABC(const std::string& in);
IPC_SEND(ABC)("QAZ")(IpcAsync);
On the server, when bytes (parameter of the IPC transport function IpcSync described above) is received from the client, IpcCall::Server::SyncCall(bytes) should be called and its return (std::vector<uint8_t>) should be sent back to the client.
On the server, when bytes (parameter of the IPC transport function IpcAync described above) is received from the client, IpcCall::Server::AsyncCall(bytes) should be called.
Every function should be registered via macro IPC_CALL_REGISTER(f).
For instance, an implementation and registration of the function declared in the client example above:
void ABC(const std::string& in) {...}
IPC_CALL_REGISTER(ABC);
The framework supports most of the STL data structures in IpcCallData.h and can be extended with custom data.
An example of client and server is in main.cpp
The framework can be tested on https://wandbox.org/permlink/c5puwAykpNub5TH0