我正在尝试在我的MonoTouch游戏中实现配对。我已经成功实现了通过GameKit连接玩家的系统,但我仍然坚持发送和接收数据。
如何将此Objective-c代码转换为c#?我要发送的数据类型是Vector2
类,其中包含X
和Y
个浮动组件。
NSError *error;
PositionPacket msg;
msg.messageKind = PositionMessage;
msg.x = currentPosition.x;
msg.y = currentPosition.y;
NSData *packet = [NSData dataWithBytes:&msg length:sizeof(PositionPacket)];
[match sendDataToAllPlayers: packet withDataMode: GKMatchSendDataUnreliable error:&error];
if (error != nil)
{
// handle the error
}
非常感谢任何帮助!
答案 0 :(得分:1)
常用方式,因为OpenTK.Vector2
用[Serializable]
修饰,将结构序列化为Stream
(例如MemoryStream
然后从中初始化一个新的NSData
,例如使用NSData.FromStream
。这样做有相当多的开销,但它适用于任何结构。
更好地使用Stream
会将您的值写入其中(例如使用StreamWriter
)。这消除了序列化开销(反射),并允许您从不同的值构建流(不创建结构)。
MemoryStream ms = new MemoryStream ();
using (StreamWriter sw = new StreamWriter (ms)) {
sw.Write (v2.X);
sw.Write (v2.Y);
}
ms.Position = 0;
var data = NSData.FromStream (ms);
更多复杂(但可能更快方式)是使用unsafe
代码和NSData.FromBytes
接受IntPtr
(指针)和数据的大小。如果您的所有数据都已经在结构中,那么这很容易做到。
hacky 方式是将Vector2
转换为monotouch.dll
中已知的类型,例如PointF
。这样您就可以使用NSData.FromObject
了。此API适用于NSObject
,NSValue
支持的最基本的价值类型和一些基本类型,或monotouch.dll
内添加的基本类型,例如RectangleF
,PointF
,...
var v2 = new OpenTK.Vector2 ();
var pt = new System.Drawing.PointF (v2.X, v2.Y);
var data = NSData.FromObject (pt);
答案 1 :(得分:0)
好的,所以我想我在很大程度上想出来了。对于任何有兴趣的人,这是我的解决方案。
unsafe
{
NSError error = new NSError((NSString)"Test", 0);
System.IntPtr pointer = Marshal.AllocHGlobal(sizeof(PointF));
PointF packedData = new PointF(position.X, position.Y);
Marshal.StructureToPtr(packedData, pointer, false);
NSData packet = NSData.FromBytes(pointer, (uint)sizeof(PointF));
currentMatch.SendDataToAllPlayers(packet, GKMatchSendDataMode.Unreliable, error.ClassHandle);
Marshal.FreeHGlobal(pointer);
}
所以我仍然不确定NSError
应该是什么,尽管对于我的项目失败的数据包并不重要。这是接收数据包的代码。
PointF packedData = (PointF)Marshal.PtrToStructure(data.Bytes, typeof(PointF));
var recievedData = new Vector2(packedData.X, packedData.Y);