4

I am developing a project using C++/CLI and WinForms. It is a geometry project, which is why I have to use C++/CLI, because of the C++ geometry library CGAL. I chose to use WinForms for the UI because compared to the other C++/CLI windows UI options it seemed rather easy to use. However, after some research online I realized that WinForms for C++/CLI makes use of managed code and that managed code is oftentimes a factor 2 slower than native code. The project is about implementing a competitive algorithm, so the running time is very important. The project will have a very simple UI form to select some parameters for the project and the running time will only be tracked for the actual computation part of the project, not for the UI interaction.

Will using WinForms, in this case, slow down the running time of the geometrical computations? Or is it okay, because the geometrical part of the code is in an "unmanaged" part. How can I make sure that it is "unmanaged"?

Deduplicator
  • 8,591
  • 5
  • 31
  • 50
Simon H
  • 151
  • 4
  • WinForms should be able to interoperate with Gdiplus (System.Drawing) for graphical drawing tasks. – rwong Oct 09 '20 at 14:01

1 Answers1

6

C++/CLI allows to mix managed and unmanaged Code within the same DLL/EXE ("assembly"). In laymans terms, a "managed" class starts with the ref class keyword, an unmanaged class is introduced without the ref keyword.

In the scenario described in the question, one will usually implement the program using (at least) three layers:

  • an unmanaged C++ layer which contains the core algorithms

  • an UI layer, probably written in C#, since the WinForms designer works best with that language

  • an intermediate managed C++/CLI layer as a "middleman" which connects the former two, and provides a managed API for the UI to access the unmanaged layer.

That way, the unmanaged layer will benefit from the full optimization capabilites of the native C++ compiler. It should be obvious one should avoid callbacks to managed functions from within the performance critical sections of the program.

If the "unmanaged layer" is part of the same assembly where the managed C++/CLI code is placed, or if it is placed in a separate lib or dll does usually not make a big difference for the performance. Technically, both approaches are possible.

Thanks to @rwong for pointing out in a comment that it might be necessary to put #pragma unmanaged into to the unmanaged C++ class files, in case one is not going to use separate libs.

Doc Brown
  • 199,015
  • 33
  • 367
  • 565
  • So as long as I don't do any callbacks from the performance critical section to the managed section, it should be fine? I use the WinForms extension for Visual Studio, which I think is C++ even though it does require .NET. – Simon H Oct 08 '20 at 22:36
  • Also, how would I go about implementing such a middleman layer? – Simon H Oct 08 '20 at 22:45
  • 1
    @SimonH: Use C# for the UI, as I said, everything else will bring you pain (no idea what "extension" you are talking of, but MS stopped providing WInforms project templates for C++/ CLI years ago). And for your second question: learn the basics first. Google for "C++/CLI tutorial", and/or get a copy of "C++/CLI in Action". And I would recommend using the term "C++/CLI" when you want to get successful google results, not just "C++" or "managed C++", – Doc Brown Oct 09 '20 at 06:14
  • Thanks! I have found a tutorial that seems informative, and I am doing exactly what you suggest: C# for UI, C++/CLI for a wrapper and native C++ for the core. I have setup the core as a static library, and then I reference and include the headers for the library in the wrapper. However, I get an error message from CGAL: "'s': object with destructor or non-aggregate type cannot be declared with thread storage duration in managed code" which seems to suggest that it is still being compiled as managed code, even if I include the CGAL headers in the native core library. Am I doing something wrong? – Simon H Oct 09 '20 at 11:35
  • @SimonH: Stackoverflow is the place where you can get help for question like this. When you ask there, make sure you include a clear description or code example necessary to reproduce the problem. – Doc Brown Oct 09 '20 at 11:46
  • 3
    @SimonH Make very sure that every unmanaged C++ source file contain a `#pragma unmanaged`. Another way of making sure that every unmanaged C++ source file is indeed treated as unmanaged by the compiler is to create an unmanaged C++ **LIB** (library) project, and then specify that library to be linked into the managed C++/CLI project. Otherwise, the binary code generated by the compiler are indeed different. – rwong Oct 09 '20 at 14:04
  • @rwong I indeed created an unmanaged C++ library and linked it to the C++/CLI project, and it is now working! – Simon H Oct 09 '20 at 15:33