3

我正在尝试在我的 MonoTouch 游戏中实现匹配。我已经成功实现了通过 GameKit 连接玩家的系统,但我一直在发送和接收数据。

我如何将这个objective-c代码转换成c#?我想发送的数据类型是一个Vector2带有XY浮动组件的类。

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
}

任何帮助将不胜感激!

4

2 回答 2

1

常用的方法,因为OpenTK.Vector2用 装饰[Serializable],将结构序列化为 a Stream(例如 a MemoryStream),然后从它初始化一个新NSData的,例如使用NSData.FromStream。这样做有相当多的开销,但它适用于任何结构。

一个更好的使用方法是Stream将你的值写入其中(例如使用 a 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);
于 2012-04-29T14:29:35.573 回答
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);
于 2012-04-30T00:49:43.853 回答