简体   繁体   中英

Memory usage from C# apps using C++ DLLs

Just to get it right, I would like to have your opinion if I am right with my imagination of how the dataflow is between a C# programm calling a C++ dll with delegates as parameter.

  1. The System gives memory to the C# program
  2. The C# Program loads the.dll and gives some of its space to the C++ dll. In this space there will be no C# Garbage Collection, only if the.dll is unloaded and then there can be freed the whole space.
  3. A C++ function is called. The specific Function has a delegate as parameter. We dive into the C++ memory area and declare some variables. The C++ function will somewhere in its Code call the C# delegate.
  4. The C# delegate operates on the C# Memory and will have a copy of its input parameters in the C# memory, if they are native types or a reference to the variables in the C++ memory, if it is a complex type. If we have native types I can just save it into the C# world and all will be fine. But if it is a reference and I just save it into my C# memory, I will get undefined behaviour, if I end my C++ function, because the variables will get out of scope and will be destroyed.
  5. The C# function ends and we get the returnvalue in C++ as copy (or a pointer to the returnvalue, if it is a complex type, the pointer will point into the C# memory)
  6. the C++ function ends and the used memory of the C++ function is released

Am I right with this?

This should be described in the documentation for the marshaller

if they are native types or a reference to the variables in the C++ memory, if it is a complex type. If we have native types I can just save it into the C# world and all will be fine. But if it is a reference and I just save it into my C# memory, I will get undefined behavior, if I end my C++ function, because the variables will get out of scope and will be destroyed

My understanding is that the marshaller will either convert complex types to structs, or pointers (IntPtr). Structs are passed by value, so you would have a copy in managed memory (probably on the stack). Pointers would need unsafe code to access, so you would be responsible for handling these safely.

C++ as copy (or a pointer to the returnvalue, if it is a complex type, the pointer will point into the C# memory)

There is not really a way a managed function can return a pointer to managed memory in a safe way. To create a pointer you would need to fix the object to preventing the GC from moving it, but fixing is scoped, so it would not work for return values.

I personally consider the marshalling rules a bit complicated, and I would prefer to keep any p/Invoke simple, if for no other reason than to avoid questions about safety. For more complicated interoperability between c# and c++ I would suggest c++/cli. This allow you to do type conversion yourself, and adds a whole host of tools you can use to ensure correct functioning.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM