0

I have the following method in C++ which returns a long string object.

std::string GetBigString() {
    // ...
}

I need to use this method in C# so I have to modify the method to return char*. I have no idea about the length of the returned string - it can be short or very long. After the method is called I will like to have full memory control over the string in C# and not store it statically in the C++ memory space. (something like copy elision from C++ to C#)

Is there a good practice to achieve this?

asmbaty
  • 436
  • 2
  • 11
  • 3
    Use C++/CLI [Quick C++/CLI - Learn C++/CLI in less than 10 minutes](https://www.codeproject.com/Articles/19354/Quick-C-CLI-Learn-C-CLI-in-less-than-10-minutes). Since you need to move from C++'s memory model (scope based) to garbage collected memory. All other solutions that avoid copying, with passing pointers back and forth require manual managment of pinning memory (so the garabage collector leaves it alone etc...) – Pepijn Kramer Jan 19 '23 at 09:44
  • 3
    Anyway this has nothing to do with "copy elision". To let C# get full control you will need to make a copy from unmanaged to managed memory. – Pepijn Kramer Jan 19 '23 at 09:48
  • 1
    https://stackoverflow.com/questions/5298268/returning-a-string-from-pinvoke – Matthew Watson Jan 19 '23 at 09:50
  • If you are using COM , then you can Use BSTR to get a string from C++ to C#. And add calling convention Cdel https://learn.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.callingconvention?view=netcore-3.1#fields – Hari E Jan 19 '23 at 10:14
  • This should be a platform-agnostic solution, for instance, work on .net core on macOS. – asmbaty Jan 19 '23 at 10:58
  • @HariE That is certainly an approach that will work, however COM does have its own learning curve which might not be needed. I've also found that you then have 3 memory life cycle mechanism to deal with : Scope based from C++, Reference count based from COM and Garbage collected from .Net. And while it works, it is another layer of indirection extra. – Pepijn Kramer Jan 19 '23 at 11:06
  • @asmbaty Then it looks like you need to use an extern "C" interface and pInvoke :( https://www.mono-project.com/docs/advanced/pinvoke/ Just use it to get the data out of C++ then copy it to a .Net string (don't try to hold on to it). A totally different solution would be to host your C++ code in a gRPC service and get to the data that way (at least that will be a fully platform agnostic solution (in the sense that gRPC is available for most platforms) – Pepijn Kramer Jan 19 '23 at 11:09

0 Answers0