I have a question about the releasing of memory when marshalling structs containing strings across pInvoke
I want to return a result struct by reference, since the calling code can not directly return structs due to being tied to .NET Framework, which does not have the ability to return structs. (https://github.com/dotnet/runtime/issues/10973#issuecomment-572207188)
In the following sample, my question is: do I need to release memory of the struct that was passed in manually in the implementation of the C++ method? Or is it all done on the managed code side (C#)?
C++:
struct Error
{
char* message = nullptr;
unsigned long code = 0;
};
struct Result
{
bool success = false;
Error error; // can be ignored if success = true
char* content = nullptr; // should be non-nullptr if success = true
};
extern "C" __declspec(dllexport) void CallWithStructRefResult(const char* input, Result& result);
C#:
public readonly record struct Error(string Message, int Code);
public record struct Result
{
[MarshalAs(UnmanagedType.I1)]
public readonly bool Success;
public readonly Error Error;
public readonly string Content;
}
I am calling it in C#
[DllImport(CppDll, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern Result CallWithStructRefResult([MarshalAs(UnmanagedType.LPUTF8Str)] string input, ref Result result);
Result returnFromCpp = new();
CallWithStructRefResult("someContentToSend", ref result);
Question here: If I pass in a
Result res = new Result { Success = false, Error = new(Message: "None", Code: 0), Content = "someLongStringThatMightNeedToBeCleanedUpBeforeCppWritesToIt" };
does the existing inner content need to be cleaned by CoTaskMemFree (or similar) in the C++ code, or is it entirely in the C# garbage collection domain, since this is where the struct was created?