Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to run unmanaged C++ normally from a managed C++/CLI project?

I'm in the process of wrapping a pure unmanaged VC++ 9 project in C++/CLI in order to use it plainly from a .NET app. I know how to write the wrappers, and that unmanaged code can be executed from .NET, but what I can't quite wrap my head around:

  1. The unmanaged lib is a very complex C++ library and uses a lot of inlining and other features, so I cannot compile this into the /clr-marked managed DLL. I need to compile this into a seperate DLL using the normal VC++ compiler.

  2. How do I export symbols from this unmanaged code so that it can be used from the C++/CLI project? Do I mark every class I need visible as extern? Is it that simple or are there some more complexities?

  3. How do I access the exported symbols from the C++/CLI project? Do I simply include the header files of the unmanaged source code and will the C++ linker take the actual code from the unmanaged DLL? Or do I have to hand write a seperate set of "extern" classes in a new header file that points to the classes in the DLL?

  4. When my C++/CLI project creates the unmanaged classes, will the unmanaged code run perfectly fine in the normal VC9 runtime or will it be forced to run within .NET? causing more compatibility issues?

  5. The C++ project creates lots of instances and has its own custom-implemented garbage collector, all written in plain C++, it is a DirectX sound renderer and manages lots of DirectX objects. Will all this work normally or would such Win32 functionality be affected in any way?

like image 902
Robin Rodricks Avatar asked Mar 24 '13 12:03

Robin Rodricks


People also ask

Can we write unmanaged code in C#?

No, there is no such thing as unmanaged C#. C# code will be always compiled into the IL code and executed by CLR. It is the case of managed code calling unmanaged code. Unmanaged code can be implemented in several languages C/C++/Assembly etc, but CLR will have no idea of what is happening in that code.

Is C++ CLI for managed?

Yes, C++/CLI has a very specific target usage, the language (and its compiler, most of all) makes it very easy to write code that needs to interop with unmanaged code. It has built-in support for marshaling between managed and unmanaged types.

Is Managed C++ deprecated?

Managed Extensions for C++ or Managed C++ is a now-deprecated set of language extensions for C++, including grammatical and syntactic extensions, keywords and attributes, to bring the C++ syntax and language to the . NET Framework.

Is Managed C++ faster than C#?

C# must first compile into Microsoft Intermediate Language (MSIL) before the just-in-time (JIT) compiler generates machine code. For this reason, C++ is typically faster than C#.


1 Answers

You can start with an ordinary native C++ project (imported from, say, Visual Studio 6.0 from well over a decade ago) and when you build it today, it will link to the current version of the VC runtime.

Then you can add a single new foo.cpp file to it, but configure that file so it has the /CLR flag enabled. This will cause the compiler to generate IL from that one file, and also link in some extra support that causes the .NET framework to be loaded into the process as it starts up, so it can JIT compile and then execute the IL.

The remainder of the application is still compiled natively as before, and is totally unaffected.

The truth is that even a "pure" CLR application is really a hybrid, because the CLR itself is (obviously) native code. A mixed C++/CLI application just extends this by allowing you to add more native code that shares the process with some CLR-hosted code. They co-exist for the lifetime of the process.

If you make a header foo.h with a declaration:

void bar(int a, int b);

You can freely implement or call this either in your native code or in the foo.cpp CLR code. The compiler/linker combination takes care of everything. There should be no need to do anything special to call into native code from within your CLR code.

You may get compile errors about incompatible switches:

  • /ZI - Program database for edit and continue, change it to just Program database
  • /Gm - you need to disable Minimal rebuild
  • /EHsc - C++ exceptions, change it to Yes with SEH Exceptions (/EHa)
  • /RTC - Runtime checks, change it to Default
  • Precompiled headers - change it to Not Using Precompiled Headers
  • /GR- - Runtime Type Information - change it to On (/GR)

All these changes only need to be made on your specific /CLR enabled files.

like image 85
Daniel Earwicker Avatar answered Oct 21 '22 10:10

Daniel Earwicker