public static T RPC <T>(string serverId, Route route, IMessage msg) { byte[] data = ProtoMessageToByteArray(msg); var ret = new RPCRes(); IntPtr pnt = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(RPCRes))); try { Marshal.StructureToPtr(ret, pnt, false); bool success = SendRPC(GoString.fromString(serverId), route, GoSlice.fromSlice <byte>(data), pnt); if (success) { ret = (RPCRes)Marshal.PtrToStructure(pnt, typeof(RPCRes)); T protoRet = GetProtoMessageFromResponse <T>(ret); FreeRPCRes(pnt); return(protoRet); } throw new Exception("RPC call failed!"); } finally { Marshal.FreeHGlobal(pnt); } }
// TODO can we make this faster with some delegate-fu? private static IntPtr RPCCbFunc(RPCReq req) { byte[] data = req.getReqData(); Route route = Route.fromString(req.route); Logger.Debug("called with route: " + route + " and data: " + Encoding.UTF8.GetString(data)); var response = new Protos.Response(); string remoteName = String.Format("{0}.{1}", route.service, route.method); IntPtr pnt = Marshal.AllocHGlobal(Marshal.SizeOf(new GoSlice())); if (!remotesDict.ContainsKey(remoteName)) { response = GetErrorResponse("PIT-404", String.Format("remote not found! remote name: {0}", remoteName)); byte[] resBytes = ProtoMessageToByteArray(response); Marshal.StructureToPtr(GoSlice.fromSlice <byte>(resBytes), pnt, false); return(pnt); } RemoteMethod remote = remotesDict[remoteName]; Logger.Debug(String.Format("found delegate: {0}", remote)); try{ var arg = (IMessage)Activator.CreateInstance(remote.argType); arg.MergeFrom(new CodedInputStream(data)); // invoke is slow :/ var ans = (IMessage)remote.method.Invoke(remote.obj, new object[] { arg }); byte[] ansBytes = ProtoMessageToByteArray(ans); response.Data = ByteString.CopyFrom(ansBytes); byte[] resBytes = ProtoMessageToByteArray(response); Marshal.StructureToPtr(GoSlice.fromSlice <byte>(resBytes), pnt, false); return(pnt); } catch (Exception e) { response = GetErrorResponse("PIT-500", e.Message); byte[] resBytes = ProtoMessageToByteArray(response); Marshal.StructureToPtr(GoSlice.fromSlice <byte>(resBytes), pnt, false); return(pnt); } }