Любой правильный способ отправки байтовых данных в Unity3D из плагина C?
просто вопрос любопытства здесь.
когда вы пишете плагины для Unity на платформе iOS, Плагины имеют ограниченную функциональность обратного вызова (от плагина, а затем до Unity). В основном эта документация: iOS плагин Unity документация
заявляет, что сигнатура функции, которую вы можете вызвать, такова:
могут вызываться только методы скрипта, соответствующие следующей сигнатуре из собственного кода: Function MethodName (message:string)
подпись, определенная в C, выглядит так:
недействительным UnitySendMessage(константный тип char* параметр obj, const чарса* метод константный тип char* МСГ);
таким образом, это в значительной степени означает, что я могу отправлять строки только в Unity.
теперь в моем плагине я использую protobuf-net для сериализации объектов и отправки их обратно в unity для десериализации. Я получил это, чтобы работать, но решением я чувствовать себя довольно уродливо и не очень элегантно вообще:
Person* person = [[[[[Person builder] setId:123]
setName:@"Bob"]
setEmail:@"bob@example.com"] build];
NSData* data = [person data];
NSString *rawTest = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
UnitySendMessage("GameObject", "ReceiveProductRequestResponse", [rawTest cStringUsingEncoding:NSUTF8StringEncoding]);
в основном я просто кодирую bytestream в строку. В единстве я тогда вам байты в строку и десериализовать оттуда:
System.Text.UTF8Encoding encoding=new System.Text.UTF8Encoding();
Byte[] bytes = encoding.GetBytes(message);
это работает. Но разве нет другого способа сделать это? Возможно, у кого-то есть идея, как это можно сделать каким-то альтернативным способом?
2 ответов
Base-64 (или другая подобная база) - правильный способ сделать это; вы не может используйте кодировку здесь (например, UTF8) - кодировка предназначена для преобразования:
arbitrary string <===encoding===> structured bytes
т. е. где байты имеют определенную структуру; это не относится к protobuf; то, что вы хотите:
arbitrary bytes <===transform===> structured string
и base-64 является наиболее удобной реализацией этого в большинстве случаев. Строго говоря, иногда вы можете подняться немного выше 64, но вам, вероятно, придется свернуть его вручную-не очень красиво. База-64 хорошо понята и хорошо поддерживается, что делает ее хорошим выбором. Я не знаю, как вы это делаете в C, но в Unity это должно быть просто:
string s = Convert.ToBase64String(bytes);
часто вы также можете избежать дополнительного буфера здесь, предполагая, что вы сериализуете в памяти в MemoryStream
:
string s;
using(var ms = new MemoryStream()) {
// not shown: serialization steps
s = Convert.ToBase64String(ms.GetBuffer(), 0, (int)ms.Length);
}
пример ответа Марк Gravell-это:
на стороне ios:
-(void)sendData:(NSData*)data
{
NSString* base64String = [data base64Encoding];
const char* utf8String = [base64String cStringUsingEncoding:NSUTF8StringEncoding];
UnitySendMessage("iOSNativeCommunicationManager", "dataReceived", utf8String);
}
и на стороне единства:
public delegate void didReceivedData( byte[] data );
public static event didReceivedData didReceivedDataEvent;
public void dataReceived( string bytesString )
{
byte[] data = System.Convert.FromBase64String(bytesString);
if( didReceivedDataEvent != null )
didReceivedDataEvent(data);
}