How to communicate between c++ and c#?

Started by
12 comments, last by ChaosEngine 10 years ago

hi,guys.

I want to make a world edit.rolleyes.gif

So i decide to use WPF as my GUI's sdk(i hadn't learned it before) and use c++ to build my core system(such as graphic sys).

The question is how to design an interface to put them working together.

By the way,i know a litter such as clr, but i doubt that the performance isn't influenced if the c++ working on the clr.

(hoping not syntax errorslaugh.png ).

Any advises or matertials can help me out?

Advertisement

You cannot use C++ objects from C# as far as I know, unless they implement some COM interfaces in which case you probably wouldn't be asking this question. You can easily call C/C++ functions from C# code assuming you've exported them correctly. Google "P/Invoke" for samples. You can also wrap you C++ objects in C++/CLI ref classes which makes those classes accessable from C# directly.

The much better option is to just stick to one language however, so unless you already have a rendering engine in C++ I highly recommend you to just go C# all the way. Also, forget about the performance differences between C# and C++. Even if there is merit to the claim that C++ is slightly faster, performance is just one of many things to consider and far from the most important one imho.

Another option is to use swig to easily write some C# bindings for your C++ core engine that you can use in your WPF editor (IMHO it's way easier than writing a C++/CLI layer).

Your options are pretty much:

1. Use something like SWIG as Colin mentioned, it basically is automatically creating bindings for you. Personally I don't like added project dependencies.

2. Use C++/CLI to talk directly between your core and your GUI platform. This isn't so bad, but does introduce essentially a third language with its own syntax that is different from C++ and C#. We do this at work (our apps are a blend between native and managed, and we have a lot of C++/CLI going on).

3. Write a C-API to essentially wrap your C++ objects, then use P/Invoke to call those. How much interaction is really going to go on between your core system and the GUI? A small C wrapper to call into probably is enough.

4. COM as DvDMan mentioned...which I wouldn't do for this, the above solutions in my opinion are more desirable.

Personally I'd go with #2 or #3 (leaning on the latter since it doesn't require learning anything new from what I presume you already know), if you wanted to write your core system in C++. But honestly, if I was doing this, both the core system and GUI would be all C#. E.g. use SharpDX for graphics.

Use something like SWIG as Colin mentioned, it basically is automatically creating bindings for you. Personally I don't like added dependencies.

What dependency are you talking about? AFAIK swig does not add any runtime dependency to your bindings, it's just a tool that you can drop in your project folder, you can even invoke it automatically whenever you rebuild your c++ project and have always up to date bindings. (note that I only used swig for python bindings, not C#).

Use something like SWIG as Colin mentioned, it basically is automatically creating bindings for you. Personally I don't like added dependencies.

What dependency are you talking about? AFAIK swig does not add any runtime dependency to your bindings, it's just a tool that you can drop in your project folder, you can even invoke it automatically whenever you rebuild your c++ project and have always up to date bindings. (note that I only used swig for python bindings, not C#).

Sorry, meant a project dependency on a third party tool in general. Not runtime dependencies.

Binding C# to C++ is hard and painful. I recommend not doing it (I will give SWIG another look).

I recently needed to bring a rather large c++ API into Unity (C#). To do this I built a very minimalist C API (just 4 functions: init, shutdown, send message, tick), which I use P/Invoke to call. I then pass messages back and forth between managed and unmanaged code using this API. Messages are code generated classes (from a simple message definition) that serialize to buffers and then passed through the sendMessage function to the other side. The code generator actually generates C++ and C# versions of the class so they know how to serialize/deserialize on either side. There's definitely a performance hit for this approach, but it is the cleanest way I came up with that still allows me to expand what is passed between managed/unmanaged code with a minimal amount of work.

You might also want to consider doing something similar but with TCP sockets. I've sat in a couple of sessions at GDC recently where people are building remote debug/edit capabilities into their game engines by passing messages over a socket, even if it's all within the same application.

Cheers,

Bob


[size="3"]Halfway down the trail to Hell...


Binding C# to C++ is hard and painful. I recommend not doing it (I will give SWIG another look).

No, it really not that bad.

soloman, if you have a well defined interface to your c++ code simply wrap that in a C++/Cli layer and you're pretty much done. You don't even need to change your existing C++ compilation settings.

if you think programming is like sex, you probably haven't done much of either.-------------- - capn_midnight

2. Use C++/CLI to talk directly between your core and your GUI platform. This isn't so bad, but does introduce essentially a third language with its own syntax that is different from C++ and C#. We do this at work (our apps are a blend between native and managed, and we have a lot of C++/CLI going on).

As long as your C++ and C#-code will use the same toolchain (e.g. Visual Studio 2013), I think this is the way to go. It's a bit of a hassle, but not as cumbersome as going to COM and P/Invoke.

Binding C# to C++ is hard and painful. I recommend not doing it (I will give SWIG another look).


No, it really not that bad.

soloman, if you have a well defined interface to your c++ code simply wrap that in a C++/Cli layer and you're pretty much done. You don't even need to change your existing C++ compilation settings.


I second this. I have had a great experience with mixed C# and C++/CLI projects.

This topic is closed to new replies.

Advertisement