5

I'm writing a unity plugin to connect Native iOS functionality to Unity.

One of the things I have to do involves sending back strings from Objective-C(iOS) to C#(Unity) which is accomplished by writing a simple C extern function.

I found this post:

https://forum.unity3d.com/threads/plugins-sending-string-data.66435/

Which suggests using this helper function which can be returned through the C extern:

// Helper method to create C string copy
char* MakeStringCopy (const char* string)
{
    if (string == NULL)
        return NULL;

    char* res = (char*)malloc(strlen(string) + 1);
    strcpy(res, string);
    return res;
}

I'm not very proficient with Unity so I don't know if this is causing a memory leak or not.

Looking at it from the pure Objective-C point of view, the function

  1. takes a char pointer
  2. allocates some memory space based on the length of the original string
  3. copies the original string into this newly allocated space
  4. returns the new copied pointer

The helper function is used within the C extern function like this:

return cStringCopy([objc_status UTF8String]);

So the memory used by the original string is managed automatically by Objective-C, however...

Once Unity receives the char pointer, will it deallocate the assigned memory automatically?

The C# unity script uses the function like this:

string someInfo = SDKWrapper_getInfo();

The answer from this question:

How to convert between a C# String and C Char pointer

Kind of relates to this (i think), so it really makes me think I have a memory leak here.

Pochi
  • 13,391
  • 3
  • 64
  • 104
  • You might want to read this answer about returning a `char *`: https://stackoverflow.com/q/370079/996081 – cbr Aug 21 '17 at 09:34

2 Answers2

1

The accepted answer is wrong. Though some people mention that this way will lead to a memory leak that is not right. This way works fine in Unity and no leaks occurs (I tested it many times). Unity clearly states that

String values returned from a native method should be UTF–8 encoded and allocated on the heap. Mono marshalling calls free for strings like this.

Full answer

Shpand
  • 661
  • 9
  • 14
0

Yes, this will leak memory. The solution would be to pass a managed chunk of memory (i.e. a StringBuilder) to the native function, i.e.:

[DllImport(...)]
private static extern int GetInfo
    ([MarshalAs(UnmanagedType.LPWStr)]StringBuilder dst, int dstCapacity);

private void SomeMethod()
{
    var sb = new StringBuilder(8192);

    // perhaps the function can indicate whether the capacity was large enough
    var success = GetInfo(sb, sb.Capacity);
}

You can see a similar example on this page.

vgru
  • 49,838
  • 16
  • 120
  • 201