【发布时间】:2016-05-05 10:07:19
【问题描述】:
我正在创建一个需要向 Unity 返回字符串(或 const char*)的 iOS 插件。如何实现?
【问题讨论】:
我正在创建一个需要向 Unity 返回字符串(或 const char*)的 iOS 插件。如何实现?
【问题讨论】:
我想澄清以前的答案。 C# 声明:
[DllImport("__Internal")]
private static extern string getString();
从 objc 返回一个字符串就像@Cabrra 说的:
char* convertNSStringToCString(const NSString* nsString)
{
if (nsString == NULL)
return NULL;
const char* nsStringUtf8 = [nsString UTF8String];
//create a null terminated C string on the heap so that our string's memory isn't wiped out right after method's return
char* cString = (char*)malloc(strlen(nsStringUtf8) + 1);
strcpy(cString, nsStringUtf8);
return cString;
}
extern "C" char* getString()
{
const NSString* str = @"string";
return convertNSStringToCString(str);
}
虽然有人提到这种方式会导致内存泄漏,这是不对的。这种方式在 Unity 中运行良好,并且不会发生泄漏(我测试了很多次)。 Unity clearly states那个
从本地方法返回的字符串值应该是 UTF-8 编码并在堆上分配。 Mono marshalling 对这样的字符串免费调用。
【讨论】:
strdup。 return strdup([nsString UTF8String]);
extern "C"
{
int _pow2(int x)
{
// Just a simple example of returning an int value
return x * x;
}
// Returns a char* (a string to Unity)
char* _helloWorldString()
{
// We can use NSString and go to the c string that Unity wants
NSString *helloString = @"Hello World";
// UTF8String method gets us a c string. Then we have to malloc a copy to give to Unity. I reuse a method below that makes it easy.
return cStringCopy([helloString UTF8String]);
}
// Here is an example of getting a string from Unity
char* _combineStrings(const char* cString1, const char* cString2)
{
// This shows we can create two NSStrings* from the c strings from Unity
NSString *string1 = CreateNSString(cString1);
NSString *string2 = CreateNSString(cString2);
NSString *combinedString = [NSString stringWithFormat:@"%@ %@", string1, string2];
// Same as before, have to go to a c string and then malloc a copy of it to give to Unity
return cStringCopy([combinedString UTF8String]);
}
}
//I also like to include these two convenience methods to convert between c string and NSString*. You need to return a copy of the c string so that Unity handles the memory and gets a valid value.
char* cStringCopy(const char* string)
{
if (string == NULL)
return NULL;
char* res = (char*)malloc(strlen(string) + 1);
strcpy(res, string);
return res;
}
// This takes a char* you get from Unity and converts it to an NSString* to use in your objective c code. You can mix c++ and objective c all in the same file.
static NSString* CreateNSString(const char* string)
{
if (string != NULL)
return [NSString stringWithUTF8String:string];
else
return [NSString stringWithUTF8String:""];
}
【讨论】:
_helloWorldString 在 C# 代码中的签名将是:static extern string _helloWorldString();。所以char*作为托管string返回Unity,不需要空闲,系统会自动释放。
cStringCopy() 与自 1960 年代后期以来在标准 C 库中的 strdup() 完全相同。