繁体   English   中英

从C插件向Unity3D发送字节数据的任何正确方法?

[英]Any proper way of sending byte data to Unity3D from a C plugin?

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

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

说明你能够回拨的函数签名是这样的:

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

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

void UnitySendMessage(const char * obj,const char * method,const char * msg);

所以这几乎意味着我只能将字符串发送回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]);

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

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

这确实有效。 但是真的没有办法做到这一点吗? 也许有人知道如何以某种替代方式完成它?

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

基于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);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM