从C插件发送字节数据到Unity3D的任何适当方式?(Any proper way of sending byte data to Unity3D from a C plugin?)

编程入门 行业动态 更新时间:2024-10-28 19:33:06
从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来序列化对象并将它们发送回统一进行反序列化。 我已经得到这个工作,但通过我觉得很难看,并且不是很优雅的解决方案:

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

这确实有用。 但是真的没有其他的方式来做这件事吗? 也许有人对如何以其他方式完成这个想法有所了解?

Just a question of curiosity here.

When you write plugins for Unity on the iOS platform, the plugins have a limited native-to-managed callback functionality (from the plugin and then to Unity). Basically this documentation: iOS plugin Unity documentation

states that the function signature you are able to call back to is this:

Only script methods that correspond to the following signature can be called from native code: function MethodName(message:string)

The signature defined in C looks like this:

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

So this pretty much means I can only send strings back to Unity.

Now in my plugin I'm using protobuf-net to serialize objects and send them back to unity to be deserialized. I have gotten this to work, but by a solution I feel is quite ugly and not very elegant at all:

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

Basically I simply encode the bytestream into a string. In Unity I then get the bytes of the string and deserialize from there:

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

This does work. But is there really no other way of doing it? Perhaps someone have an idea of how it could be done in some alternative way?

最满意答案

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

Base-64 (or another similar base) is the correct way to do this; you cannot use an encoding here (such as UTF8) - an encoding is intended to transform:

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

i.e. where the bytes have a defined structure; this is not the case with protobuf; what you want is:

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

and base-64 is the most convenient implementation of that in most cases. Strictly speaking, you can sometimes go a bit higher than 64, but you'd probably have to roll it manually - not pretty. Base-64 is well-understood and well-supported, making it a good choice. I don't know how you do that in C, but in Unity it should be just:

string s = Convert.ToBase64String(bytes);

Often, you can also avoid an extra buffer here, assuming you are serializing in-memory to a MemoryStream:

string s; using(var ms = new MemoryStream()) { // not shown: serialization steps s = Convert.ToBase64String(ms.GetBuffer(), 0, (int)ms.Length); }

更多推荐

本文发布于:2023-07-05 00:56:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1031209.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:字节   插件   方式   数据   data

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!