Jump to content

  • Log In with Google      Sign In   
  • Create Account

How to communicate between c++ and c#?


Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.


  • You cannot reply to this topic
13 replies to this topic

#1 soloman   Members   -  Reputation: 126

Like
0Likes
Like

Posted 03 April 2014 - 05:12 AM

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?



#2 DvDmanDT   GDNet+   -  Reputation: 1515

Like
1Likes
Like

Posted 03 April 2014 - 06:17 AM

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.



#3 ColinDuquesnoy   Members   -  Reputation: 1162

Like
0Likes
Like

Posted 03 April 2014 - 06:26 AM

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).



#4 Starnick   Members   -  Reputation: 1710

Like
2Likes
Like

Posted 03 April 2014 - 06:54 AM

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.


Edited by Starnick, 03 April 2014 - 08:11 AM.


#5 ColinDuquesnoy   Members   -  Reputation: 1162

Like
-1Likes
Like

Posted 03 April 2014 - 07:34 AM

 

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#).



#6 Starnick   Members   -  Reputation: 1710

Like
1Likes
Like

Posted 03 April 2014 - 07:58 AM

 

 

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.



#7 Scourage   Members   -  Reputation: 1048

Like
1Likes
Like

Posted 03 April 2014 - 08:59 AM

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



Halfway down the trail to Hell...

#8 ChaosEngine   Crossbones+   -  Reputation: 4291

Like
1Likes
Like

Posted 03 April 2014 - 02:08 PM


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

#9 DaBono   Members   -  Reputation: 1390

Like
0Likes
Like

Posted 04 April 2014 - 03:04 PM

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.



#10 Nypyren   Crossbones+   -  Reputation: 10069

Like
1Likes
Like

Posted 04 April 2014 - 06:00 PM

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.

#11 Hodgman   Moderators   -  Reputation: 48364

Like
1Likes
Like

Posted 05 April 2014 - 04:59 PM

In the past I've either made a. C wrapper for my C++, which I've then wrapped in C#, or I've wrapped my C++ in C++/CLI, which makes it usable in C#.

However, recently I had to do a job that required calling x64(64bit) C++ code from an x86(32bit) C# program - the standard solutions don't work in this situation!
So instead, I made two processes - one C# x86 and one C++ x64, and had then communicate via a Win32 pipe object (wrapped in a binary reader/writer on the C# end, and just using the Win32 API on the C++ end). It turned out to be really simple and I actually enjoyed using the network-esque style of communication.

One advantage of this is a kind of crash isolation / sandboxing. If your C# GUI crashes, then the core engine par of your editor is still running and you haven't lost any data - you can just restart the GUI.
Insomniac do this with their tools, with the core editor logic runnin in an engine process, and the GUIs actually running inside your web browser!

#12 Nypyren   Crossbones+   -  Reputation: 10069

Like
0Likes
Like

Posted 05 April 2014 - 05:13 PM

So instead, I made two processes - one C# x86 and one C++ x64, and had then communicate via a Win32 pipe object (wrapped in a binary reader/writer on the C# end, and just using the Win32 API on the C++ end). It turned out to be really simple and I actually enjoyed using the network-esque style of communication.


I did something similar for my debugger:

AnyCPU C# WinForms app <-> named pipe <-> Hybrid C# & C++/CLI debughost processes (one targeting x86, one x64).

Each debughost process is primarily C#, using the same named pipe C# DLL that the WinForms app used, which eliminated needing to write the named pipe code in both C# and C++. Each debughost has its own 32-bit or 64-bit Win32 debugging code written in C++/CLI to do the actual debugging, and a really simple C# glue to bind the named pipe code and C++/CLI code together.

This allows one instance of the GUI interface to debug both 32-bit and 64-bit processes at the same time. I was initially a bit worried about performance, but it can transfer data at over a gigabyte per second, which is far more than I need.

Edited by Nypyren, 05 April 2014 - 05:18 PM.


#13 JohnnyCode   Members   -  Reputation: 1020

Like
0Likes
Like

Posted 06 April 2014 - 08:15 AM

There are certain obstacles about c++/CLI . You are unable to (or rather strictly soudn't) pass pointers of memory from C# module to c++ module, so you must think well about the CLI wraper you are to write and use. If you do interchange memory , you will screw yourself up with "unsafe" keyword, making C# actualy unsafe language again. CLI will force you to a very intensive isolation on the other hand, what is good, yet, you will have to clone memory/data you pass from C# to c++. The memory c++ module uses, must be allocated by this module, C# will only instruct the values to use in it. If you are a good programmer, your CLI module will be just perfect, but you should definitely know and learn CLI vitals. Not every c++ module has a good wraping "score", in such cases, you wrap only user-data-unoperating functions, zombie/initialization functions, and rewrite the very user data operative functions to the actual C# (what CLI module offers itslef). CLI is actualy code that can operate on C# memory (and types), and operate on native memory (and types), to allow one invoke deeper c++ modules instructions, while keeping distinction between those memories and its managing.



#14 ChaosEngine   Crossbones+   -  Reputation: 4291

Like
0Likes
Like

Posted 06 April 2014 - 03:42 PM

In the past I've either made a. C wrapper for my C++, which I've then wrapped in C#, or I've wrapped my C++ in C++/CLI, which makes it usable in C#.

However, recently I had to do a job that required calling x64(64bit) C++ code from an x86(32bit) C# program - the standard solutions don't work in this situation!
So instead, I made two processes - one C# x86 and one C++ x64, and had then communicate via a Win32 pipe object (wrapped in a binary reader/writer on the C# end, and just using the Win32 API on the C++ end). It turned out to be really simple and I actually enjoyed using the network-esque style of communication.

One advantage of this is a kind of crash isolation / sandboxing. If your C# GUI crashes, then the core engine par of your editor is still running and you haven't lost any data - you can just restart the GUI.
Insomniac do this with their tools, with the core editor logic runnin in an engine process, and the GUIs actually running inside your web browser!

I always liked the idea of embedding a web server in your engine


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




Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.




PARTNERS