tags:

views:

2899

answers:

9

We have a monolithic MFC GUI app that is nearing the end of it's life in C++. We are planning to build new functionality in C# and pass data between each app.

Question is: What is the best approach for passing data between C++ and C#?

Notes:
Both ends will have a GUI front end and will probably only need to pass simple data like Id's and possibly have a mechanism where it indicates to the other app what process/functionality to use.
Eg One of the applications will be a CRM system in C# that when a row in a grid is double clicked would pass say the customerId and a message to open that customer in the Customer Form of the MFC app.

I have done a little bit of research, the options seem to be Windows Messaging, Memory Mapping, Named Pipes or something like Windows Sockets. At this stage we are leaning towards Named Pipes, but would really appreciate other advice or tips or other peoples experiences.

+2  A: 

You can also use P/Invoke from the managed side - this would be useful if the MFC app has a C API. Also you can use COM from either side.

1800 INFORMATION
A small comment as to why the downvote is always nice
1800 INFORMATION
+2  A: 

The options you list are certainly valid, but you could also consider COM.

QBziZ
Surely you mean DCOM?
Shaun Austin
Either COM or DCOM would be appropriate - depending on whether the app is running on the same machine or not
1800 INFORMATION
@Shaun Austin : Actually I meant COM :), that's why I said COM.
QBziZ
My bad, sorry, been a while and forgot about COM EXEs being out of process! *embarrassed*
Shaun Austin
Don't worry, your reputation is untarnished, there are no arrows next to a comment []-]
QBziZ
+4  A: 

Personally I'd be thinking of using something like named pipes as they are easy to use from the C++ side and the System.IO.Pipes on the .NET side also.

It would also be the path of probably least resistance if you're planning to replace the other non .NET bits of the app over time.

Shaun Austin
Note that since .NET 2.0, named pipes are supported via the <code>System.IO.Pipes</code> namespace. There's no need for DllImports.
OwenP
I didn't know that thanks OwenP (edited to reflect that!)
Shaun Austin
+3  A: 

Take your pick:

  • files
  • named pipes <-- My recommendation
  • shared memory
  • sockets
  • COM
  • Windows messages

Why named pipes?

  • Gives you a FIFO way of working for free (like sockets, but not like shared memory)
  • Can easily communicate both ways
  • Well supported on all platforms
  • Easy to use
  • Reliable data passing and delivery
  • Can be blocking and non blocking
  • Can read data without removing (unlike sockets)
  • Can be expanded to include a third app easily.

In .Net just use System.IO.Pipes.

In C++ use CreateNamedPipe and CreateFile.

Brian R. Bondy
Not a file! I've had nothing but trouble working on systems where it writes to a file in one program and (via polling) reads the changes in another program.
Aardvark
Ah yes but surely you can create another file to let the first file know you're done working with it. Just kidding :) It's just an option, not a recommended one :)
Brian R. Bondy
No just rename/delete/move the file! File in use? Just loop and keep trying! AAAA! :)
Aardvark
Actually it could be done pretty cleanly. Register for file system notifications. Let's say program A uses file.p1 when it is using it and renames to .avail when it's not. program 2 registers for file system notifications for the .avail file.
Brian R. Bondy
... When program 2 is using it, it uses file.p2. Then each program can implement a queue of data waiting to go into the file.
Brian R. Bondy
file transfer is a widely used mechanism, you write a file per message/transaction and another app waits for a directory change notification to read it in. Its very easy to do, but better for 3rd party comms.
gbjbaanb
ya there's a million ways to do it.
Brian R. Bondy
+2  A: 

I'd use sockets (TCP) - both MFC and .NET have direct support for them.

Aardvark
A: 

My picks would be either standard window messages (e.g. WM_FOO) or DCOM:

  • Messages would work as long as the communication is very simple, and the overhead in setting it up is minimal. If you can boil the communication down to one or two integers per message, this would probably be a good place to start. If both apps are already windowed applications, they both already have message loops, so you're already most of the way there.

  • DCOM requires a lot more programmer overhead, but it's nice in that you can define a richer interface and avoid having to convert complex messages to/from binary form. If you go this route, CoRegisterClassObject is the starting point for publishing an object via DCOM. I've never tried doing this from a C# app, but in principle it should be entirely possible

Charlie
+1  A: 

Do you really need two processes?

Unmanaged C++ and managed C# code is perfectly capable of operating in the same process, and with a small layer of managed C++/CLI, you could replace the complexity of interprocess communication with simple function calls.

Rasmus Faber
A: 

Assuming you have the source to the legacy app, see if you can't compile all the "workhorse" code as a DLL, then invoke the individual functions/windows from there. Once you have that working, you can simply write Managed C++ wrappers around the functions you need, and invoke those from your C# code. The whole process can take less than a day, if you're lucky.

Coderer
A: 

I would say C++/CLI if you don't have to worry about the .NET framework existing on all the systems the app will run on, and COM otherwise. It would really depend on what you're most comfortable and familiar with, though. I like the existing 'function call' structure of C++/CLI and COM (as opposed to building it with other protocols), but that's just me.

I'm currently using COM to add some .NET component functionality, mainly due to the need to still function with fallbacks if .NET is not present, but that's specific to my needs where maximum deployment is preferable.

Nick