3

My function that returns a string looks like this in c#:

[return: MarshalAs(UnmanagedType.LPWStr)]
public static string? GetText()
{
  return SomeClass.SomeMethodThatReturnsAString();
}

And function that gets that string looks like this in cpp:

void OnWriteValue()
{
  char16_t const *string = GetText();

  if (string)
  {
    someMethodThatPrints(string);
    freeMemoryThatIsAllocatedInCSharp(string);
  }
}

And my question is how to implement "freeMemoryThatIsAllocatedInCSharp" considering that the code is used on windows and linux?

I thought GlobalFree is the solution here but there is no GlobalFree on linux.

8
  • 2
    How could you call a managed method like this? Commented Jul 24 at 8:36
  • 3
    this is the proper way to pass strings Passing strings from C# to C++ DLL and back -- minimal example Commented Jul 24 at 8:39
  • 2
    if my intuition is correct then this function should free that memory, Marshal.FreeHGlobal, but i don't know if it is correct to pass it that pointer. (because it may not point to the start of the allocated memory), so the whole thing is not recommended., just stick with the answer i linked. Commented Jul 24 at 8:42
  • 9
    Just don't, C# and C++ have very different memory managment models, so never let C++ code manage C# memory (or the other way around). What you need is a way to pin the C# memory for as long as the call to your C++ is active and then let C# garbage collector delete it afterward. Commented Jul 24 at 9:04
  • 1
    C++ code should never release memory allocated by C# code and vice versa. At most, it would pass string back to a C# function that takes care of any cleanup it requires. So the function freeMemoryThatIsAllocatedInCSharp(string) would be implemented in C#. Commented Jul 24 at 11:04

1 Answer 1

2

I ended up declaring a function that deallocates memory that was allocated and returned to cpp code earlier.

And my code looks like this:

public static IntPtr GetText()
{
  return Marshal.StringToCoTaskMemUni(SomeClass.SomeMethodThatReturnsAString());
}

public static void FreeMemory(IntPtr ptr)
{
    Marshal.FreeCoTaskMem(ptr);
}
void OnWriteValue()
{
  char16_t const *string = CSharp::GetText();

  if (string)
  {
    Print(string);
    CSharp::FreeMemory(string);
  }
}

Thanks for your answers.

Sign up to request clarification or add additional context in comments.

1 Comment

don't forget to accept your own answer if your solution works, to signal to people there is a solution

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.