I have this task of designing a new interface for a distributed application (multiple processes running on a single computer, not physically distributed – yet) which is comprised of many graphical panel modules written in C++/OpenGL and a single module written in Ada.
The modules share information on the form of parameters (pieces of scalar non-structured information e.g.: ints, strings, floats, etc…). I intend to design an asynchronous socket based component (which I’ll call hereafter ‘Interface Component’ or IC) to be linked by each module based on Boost::Asio library with two simple ‘client’ primitives:
Put([ParameterName], [DestinationModule], [Payload], [Type])
Get([ParameterName], [Sourcemodule], [Payload])
ParameterName: Designates a unique parameter name
DestinationModule/SourceModule: Addresses a module in the system
Payload: Actual data
Type: string or value that identifies the type of the passed parameter
Each of these primitives are treated on the server-side by two corresponding functions (on the IC):
//No function parameters shown here as I don't know
//exactly how I'm going to do this
ProcessPutRequest()
ProcessGetRequest()
Because the processing of incoming commands will be started by the IC, I intend to use function handlers which will be passed to the functions above. This way each programmer responsible by each module can process incoming commands and perform the necessary type conversions on his own code.
The question is… is this possible in Ada? I know one can import functions in C++ and call it from Ada programs btu is it possible to pass function handlers from Ada to a C++ component?
(a side-question is: do you have any suggestion of a better way of implementing this interface?)
Not sure what the semantics of
Get()are. Does it wait for new data? return the last data received? (in which case, what happens if no data has been received yet?)Assuming a callback scheme and Ada 2005, you might for a start consider a spec like
I’m assuming that the IC will organise marshalling and the list of registered callbacks.
One point to be wary of: in this scheme, the Receiver procedure is called in the context of a foreign (non-Ada) thread which may cause problems with the Ada runtime’s tasking support. Assuming you’re using GNAT, you should look at
GNAT.Threads(fileg-thread.adsin the runtime). You need to get the thread registered as soon as possible, for example before doing anyStringoperations such as catenation.