5

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"?

1
  • WinForms should be able to interoperate with Gdiplus (System.Drawing) for graphical drawing tasks.
    – rwong
    Commented Oct 9, 2020 at 14:01

1 Answer 1

7

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.

7
  • 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
    Commented Oct 8, 2020 at 22:36
  • Also, how would I go about implementing such a middleman layer?
    – Simon H
    Commented Oct 8, 2020 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
    Commented Oct 9, 2020 at 6: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
    Commented Oct 9, 2020 at 11:35
  • 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
    Commented Oct 9, 2020 at 14:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.