8

这里只是一个好奇的问题。

当您在 iOS 平台上为 Unity 编写插件时,插件具有有限的本地到托管回调功能(从插件到 Unity)。基本上这个文档: iOS 插件 Unity 文档

声明您可以回调的函数签名是这样的:

只能从本机代码调用与以下签名相对应的脚本方法: function MethodName(message:string)

C 中定义的签名如下所示:

void UnitySendMessage(const char* obj, const char* 方法, const char* msg);

所以这几乎意味着我只能将字符串发送回 Unity。

现在在我的插件中,我使用 protobuf-net 序列化对象并将它们发送回统一进行反序列化。我已经让它工作了,但是通过一个解决方案,我觉得它很丑陋,而且一点也不优雅:

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]);

基本上我只是将字节流编码成一个字符串。然后在 Unity 中获取字符串的字节并从那里反序列化:

System.Text.UTF8Encoding encoding=new System.Text.UTF8Encoding();
Byte[] bytes = encoding.GetBytes(message);

这确实有效。但是真的没有别的办法了吗?也许有人知道如何以其他方式完成它?

4

2 回答 2

4

Base-64(或其他类似的基础)是这样做的正确方法;您不能在此处使用编码(例如 UTF8) - 编码旨在转换:

arbitrary string <===encoding===> structured bytes

即字节具有定义的结构;protobuf 不是这种情况;你想要的是:

arbitrary bytes <===transform===> structured string

在大多数情况下,base-64 是最方便的实现。严格来说,你有时可以比 64 高一点,但你可能不得不手动滚动它 - 不漂亮。Base-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);
}
于 2012-09-05T15:08:46.247 回答
3

基于 Marc 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);
}
于 2014-05-15T11:27:25.957 回答