【问题标题】:Objective-C to C to C# unity wrapper possibly causing memory leak?Objective-C 到 C 到 C# 统一包装器可能导致内存泄漏?
【发布时间】:2017-08-21 08:46:54
【问题描述】:

我正在编写一个统一插件来将原生 iOS 功能连接到 Unity。

我必须做的一件事是将字符串从 Objective-C(iOS) 发送回 C#(Unity),这是通过编写一个简单的 C 外部函数来完成的。

我找到了这篇文章:

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

建议使用这个可以通过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;
}

我对 Unity 不是很精通,所以我不知道这是否会导致内存泄漏。

从纯Objective-C的角度来看,函数

  1. 接受一个字符指针
  2. 根据原字符串的长度分配一些内存空间
  3. 将原始字符串复制到这个新分配的空间中
  4. 返回新复制的指针

辅助函数在 C 外部函数中使用如下:

return cStringCopy([objc_status UTF8String]);

所以原始字符串使用的内存是由Objective-C自动管理的,但是...

Unity一旦收到char指针,会自动释放分配的内存吗?

C# unity 脚本使用如下函数:

string someInfo = SDKWrapper_getInfo();

这个问题的答案:

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

有点与此有关(我认为),所以这真的让我觉得我这里有内存泄漏。

【问题讨论】:

标签: c# ios objective-c c memory-leaks


【解决方案1】:

接受的答案是错误的。虽然有人提到这种方式会导致内存泄漏,这是不对的。这种方式在 Unity 中运行良好,并且不会发生泄漏(我测试了很多次)。 Unity clearly states那个

从本地方法返回的字符串值应该是 UTF-8 编码并在堆上分配。 Mono marshalling 对这样的字符串免费调用。

Full answer

【讨论】:

    【解决方案2】:

    是的,这会泄漏内存。解决方案是将托管内存块(即StringBuilder)传递给本机函数,即:

    [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);
    }
    

    您可以在 this page 上看到类似的示例。

    【讨论】:

      猜你喜欢
      • 2017-02-20
      • 1970-01-01
      • 1970-01-01
      • 2015-02-17
      • 2011-06-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多