Любой правильный способ отправки байтовых данных в 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);
}