13

I have a project in which I'll have to process 100s if not 1000s of messages a second, and process/plot this data on graphs accordingly. (The user will search for a set of data in which the graph will be plotted in real time, not literally having to plot 1000s of values on a graph.)

I'm having trouble understanding using DLLs for having the bulk of the message processing in C++, but then handing the information into a C# interface. Can someone dumb it down for me here?

Also, as speed will be a priority, I was wondering if accessing across 2 different layers of code will have more of a performance hit than programming the project in its entirety in C#, or of course, C++. However, I've read bad things about programming a GUI in C++; in regards to which, this application must also look modern, clean, professional etc. So I was thinking C# would be the way forward (perhaps XAML, WPF).

Thanks for your time.

Bondolin
  • 2,793
  • 7
  • 34
  • 62
Sparky
  • 415
  • 2
  • 5
  • 13
  • 7
    A few 1000 messages is not that much. Unless they're really complicated C# should be able to work with them too. And C++ offers decent GUI libraries (QT is supposed to be ok). So I think all three solution are probably workable. – CodesInChaos Oct 30 '10 at 13:14
  • Apologies, I just saw your comment. Cheers :D I wasn't sure if 1000-2000 messages at any one point was a lot or not. I posted this below "Effectively, I'll be taking each message and parsing it, storing it in a human readable form, then displaying it in a GUI. As far as I can see the parsing and storing will be continuely happening while the certain elements of GUI e.g graphs, tables will display on demand (querying the data / user interaction)" Any thoughts? Again, thanks for the help! – Sparky Oct 30 '10 at 19:20
  • What do you mean with "parsing" how complex is that? And how complicated is the storing in human readable form? – Vilx- Oct 30 '10 at 19:34
  • Sorry, I mean like the data will be unreadable at the start but I'm going to have to apply transformations to each message in order to store it in a way in which it can be easily read and output to screen to be read. Let's say for example, if I was taking data from an exchange I'd want to store it so that the user can see best bid/ best ask + other relevant information easily. Does that clear it up at all? – Sparky Oct 30 '10 at 19:46
  • Honestly, I don't understand this discussion... Are you afraid your data transformations could be slow if written in C# (before you ever tried)? – Paul Michalik Oct 30 '10 at 21:08
  • Hmmm I guess. I just wanted to make an educated decision on what language I should use from the outset. I didn't want to use C# to find that it wasn't fast enough, though obviously I know now that this is ridiculous because at the end of the day it's about how I optimize my code. Cheers for the help anyway guys. I think I'll do it all in C#, I quite like the powerful GUI possibilities with xaml/wpf, and I'm familiar with it as it is. – Sparky Oct 30 '10 at 21:20

5 Answers5

11

The simplest way to interop between a C/C++ DLL and a .NET Assembly is through p/invoke. On the C/C++ side, create a DLL as you would any other. On the C# side you create a p/invoke declaration. For example, say your DLL is mydll.dll and it exports a method void Foo():

[DllImport("mydll.dll")]
extern static void Foo();

That's it. You simply call Foo like any other static class method. The hard part is getting data marshalled and that is a complicated subject. If you are writing the DLL you can probably go out of your way to make the export functions easily marshalled. For more on the topic of p/invoke marshalling see here: http://msdn.microsoft.com/en-us/magazine/cc164123.aspx.

You will take a performance hit when using p/invoke. Every time a managed application makes an unmanaged method call, it takes a hit crossing the managed/unmanaged boundary and then back again. When you marshal data, a lot of copying goes on. The copying can be reduced if necessary by using 'unsafe' C# code (using pointers to access unmanaged memory directly).

What you should be aware of is that all .NET applications are chock full of p/invoke calls. No .NET application can avoid making Operating System calls and every OS call has to cross into the unmanaged world of the OS. WinForms and even WPF GUI applications make that journey many hundreds, even thousands of times a second.

If it were my task, I would first do it 100% in C#. I would then profile it and tweak performance as necessary.

Tergiver
  • 14,171
  • 3
  • 41
  • 68
  • 1
    It's arguable which is simpler, but C++ interop (by passing /clr to the Visual C++ compiler) is definitely faster than p/invoke. – Ben Voigt Oct 30 '10 at 19:37
  • I think I'm starting to sway towards the C# option. I should mention that I'll actually have to *learn* C++ before doing this whereas I know C#. I've been reading that C++ is only faster should the person be an expert in optimisation, in which, being new to C++, this would definitely not be the case. Cheers for your help. – Sparky Oct 30 '10 at 19:50
7

If speed is your priority, C++ might be the better choice. Try to make some estimations about how hard the calculation really is (1000 messages can be trivial to handle in C# if the calculation per message is easy, and they can be too hard for even the best optimized program). C++ might have some more advantages (regarding performance) over C# if your algorithms are complex, involving different classes, etc.

You might want to take a look at this question for a performance comparison.

Separating back-end and front-end is a good idea. Whether you get a performance penalty from having one in C++ and the other in C# depends on how much data conversion is actually necessary.

I don't think programming the GUI is a pain in general. MFC might be painful, Qt is not (IMHO).

Maybe this gives you some points to start with!

Bondolin
  • 2,793
  • 7
  • 34
  • 62
Philipp
  • 11,549
  • 8
  • 66
  • 126
4

Another possible way to go: sounds like this task is a prime target for parallelization. Build your app in such a way that it can split its workload on several CPU cores or even different machines. Then you can solve your performance problems (if there will be any) by throwing hardware at them.

Vilx-
  • 104,512
  • 87
  • 279
  • 422
  • This is actually a really good idea, I never thought of that. I'll need to do a bit of research into it but cheers for the idea! – Sparky Oct 30 '10 at 19:48
  • 1
    @Sparky - Don't hesitate to show your gratitude with an upvote! ;) – Vilx- Oct 31 '10 at 06:45
  • I can't up vote yet :( I already said that above... When I can I will. – Sparky Oct 31 '10 at 09:19
  • 1
    @Sparky - you have been blessed by the powers that are with the ability to cast a vote upwards, be it for a question, answer or comment. Use it wisely! – Vilx- Oct 31 '10 at 09:30
3

If you have C/C++ source, consider linking it into C++/CLI .NET Assembly. This kind of project allows you to mix unmanaged code and put managed interfaces on it. The result is a simple .NET assembly which is trivial to use in C# or VB.NET projects.

There is built-in marshaling of simple types, so that you can call functions from the managed C++ side into the unmanaged side.

The only thing you need to be aware of is that when you marshal a delegate into a function pointer, it doesn't hold a reference, so if you need the C++ to hold managed callbacks, you need to arrange for a reference to be held. Other than that, most of the built-in conversions work as expected. Visual Studio will even let you debug across the boundary (turn on unmanaged debugging).

If you have a .lib, you can use it in a C++/CLI project as long as it's linked to the C-Runtime dynamically.

Bondolin
  • 2,793
  • 7
  • 34
  • 62
Lou Franco
  • 87,846
  • 14
  • 132
  • 192
1

You should really prototype this in C# before you start screwing around with marshalling and unmarshalling data into unsafe structures so that you can invoke functions in a C++ DLL. C# is very often faster than you think it'll be. Prototyping is cheap.

Robert Rossney
  • 94,622
  • 24
  • 146
  • 218
  • 1
    I don't really have the time to prototype it as this will be my Final Year Project, but I think I will just go with programming it in C# in it's entirety. Cheers :) – Sparky Oct 31 '10 at 09:24
  • Well, okay, but a key point about prototyping is that it doesn't take a lot of time. It's also a fast way to get to what Fred Brooks was talking about when he said "Build one to throw away." – Robert Rossney Oct 31 '10 at 17:55