Connect C / C ++ with .NET.

I am considering porting a C / C ++ application to the C ++ + CLI.

Basically, I would like to use the reflection potential, XML serialization, and generally all the features of the .NET Framework offered by Microsoft (possibly even in mono).

In this project, STL is not used heavily, and application objects are mainly distributed statically. A lot of code is written in C, the other is implemented in C ++.

The problem is that the code is very, very, very "long": this is the problem for the time it takes to convert the existing code so that it works correctly.

I tried to create a C ++ project compiled with the flag in / clr, after all, it was not so bad. you can save the existing C ++ code, but in the meantime use the “managed” classes, even access the “managed” objects from the methods of the C ++ class.

The shortcomings that I found are very few, but make me puzzled by this "migration" ...

To use data serialization with reflection, all my data structures must be managed. An unmanaged class cannot declare fields defined by the type of the managed class. To solve this problem, if the class is transformed so that it is controlled by the garbage collector, each class that also declares a member of this type.

What difficulties might arise when introducing managed classes?

Well, I'm thinking about:

  • String management (I don't like to call AllocaHGlobal to convert System.String to char * every time I need it (for example, as a function parameter)
  • Array management (converting classic arrays to cli :: array)
  • (already mentioned) a mixture of managed and unmanaged classes
  • Exception Handling
  • Creating a backup of a crash (core), how it affected
  • ... any other that I have not thought of ...
+4
source share
2 answers

Unmanaged classes can have managed elements. The trick is to use the gcroot template. Look at here

http://weblogs.asp.net/kennykerr/archive/2005/07/12/Mixing-Native-and-Managed-Types-in-C_2B002B00_.aspx

to learn more about this.

EDIT: as an answer to some of your other questions: when you have a working C ++ code base that is so large that you should expect change requests from production while you are working on a C ++ / CLI port in parallel , IMHO, the best approach is to avoid having two copies of the same code base. Instead, try making the same code compile with both C ++ and C ++ / CLI using #ifdef 's, macros, generators, etc. I know that this is possible, because this is exactly what we did some time ago when porting the program ~ 120,000 lines of code.

To convert strings, we used this code:

 typedef System::String^ SysString; inline SysString Std2Sys(const std::string &s) { return gcnew System::String(s.c_str()); } inline std::string Sys2Std(SysString ss) { using namespace System::Runtime::InteropServices; const char* chars = (const char*)(Marshal::StringToHGlobalAnsi(ss)).ToPointer(); std::string s = chars; Marshal::FreeHGlobal(System::IntPtr((void*)chars)); return s; } 

(performance has never been a problem in our case, it may differ from you, but do not try to optimize anything if there is no need).

+2
source

Doc Brown speaks well of gcroot . Conversely, managed classes can have pointers to their own "subobjects."

As a rule, it is desirable to create interop variants on auto_ptr or shared_ptr , therefore, the compiler generates all templates to discard subobjects when the parent object dies, even with a combination of managed and unmanaged.

If string conversion puts you in motion, you can see the marshall_as template included in C ++ / CLI.

+1
source

Source: https://habr.com/ru/post/1335456/


All Articles