You are dealing with a problem of inter-process communication with the constraint that this needs to be platform independent and with the other constraint (that frees up more design options) that its on the same machine.
There is nothing inherently wrong with this approach. I recall Mathematica uses this approach (the calculation engine ('kernel') and the gui are two separate parts - this allowed you to run it on the same machine, or put the calculation engine on a headless unix box out there and display the gui on your desktop). There are many reasons why this structure works and works nicely.
On the other hand, you are adding complexity to the system by separating the two parts so strictly. This can be a good, or it might not. Another bit with such a structure is that the arms length distance between the two parts can allow for some easier licensing options (the gui has a GPL library in it, but you don't want to GPL the backend).
Similar things are also done with other client/server systems. Perforce (a version control system) has a server and clients (custom build for each platform) - keeping the client and the server as very distinct programs helps maintain a separation of concerns rather than having a giant application that can be harder to maintain.
Straight up linking of the application as one application can be the simplest approach with the fewest design issues... but since you don't want to do that...
The shared resource
The shared file
The simplest is that of a shared file (or files) that each write to and read from. Thats really easy (I recall a game from the early days - Spaceward Ho that used a shared file for a local area game). It works, though it is kind of clunky.
The shared fifo
A variation on this is a named pipe which looks like a file, but isn't. Well, it is a file, in that it's a file, but it's actually the output (or input) of a program that can be accessed as if it was a file.
The shared memory
You could also go with a segment of memory that multiple processes can write to. A nice bit about shared memory is that it is harder to eavesdrop on its communication (if that is an issue). It can also be rather fast. This does take appropriate synchronization of the resource. With files and fifos, the OS often has a little bit of safety to prevent you from stepping on your toes too hard (the file is locked, you an't write to it). Shared memory doesn't have as strong protections from shooting yourself in the foot.
Most systems have some sort of signals. This works, but isn't able to carry data. Its more like "hey, wake up!" type information. So, while I am listing it here, it isn't what you are looking for at all.
You are likely working on a system that allows for socket based communication. You can open up a socket (listening on localhost) and put data in it. It's really quite straight forward. It works nicely for 1:1 communication... though if you have multiple clients possibly running things could get a bit hairy if you aren't expecting it.
You can fire up (or embed) one of an enormous list of message queues. The names you'll hear most often are ActiveMQ, ZeroMq, and RabbitMQ. They all are worth looking into. If you are open to other options, there are a number of commercial entries into this area. These have the advantage that if you wanted to do something other than C++ as a client language (say, you find that your front end would be better served with .Net on a windows box), it is still easy to use this.
Message passing (remote method invocation / remote procedure call)
Staying within a language framework gives you some other options. Within Java, for example, there's Java's RMI which allows you to call one a method in one JVM from another another JVM.
C++ doesn't have RPC or RMI build in, but there are numerous libraries out there that provide this. Options like XML-RPC. I'll make mention of thrift as something and that its also cross language.