SerializationException:访问MarshalByRefObject时的二进制格式无效

时间:2017-01-26 11:20:34

标签: c# unity3d dll remoting marshalbyrefobject

我正在尝试从另一个C#应用程序向Unity应用程序发送一个锯齿状的浮动数组。

我得到了一个使用MarshalByRefObject的C#dll,并为一个简单的测试服务器应用程序和一个简单的测试客户端应用程序打开了一个Ipc通道。这两个应用程序都能够成功共享数据。这是dll的代码:

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Ipc;

namespace U2SDLL
{
    /// <summary>
    /// shared object
    /// </summary>
    public class U2SSharedObject : MarshalByRefObject
    {
        public Int32 IntegerValue { get; set; }
        public Single[] DataArray { get; set; }

        /// <summary>
        /// iitialize array
        /// </summary>
        /// <param name="arraysize">Single array size</param>
        /// <returns>=true:succeeded =false:failed</returns>
        public Boolean Init(Int32 arraysize)
        {
            IntegerValue = 0;
            DataArray = new Single[arraysize];
            return true;
        }

        /// <summary>
        /// avoid disconnection
        /// </summary>
        public override object InitializeLifetimeService()
        {
            return null;
        }
    }

    /// <summary>
    /// server class
    /// </summary>
    public class U2SServer
    {
        public U2SSharedObject SharedObject { get; set; }

        /// <summary>
        /// constructor
        /// </summary>
        public U2SServer()
        {
            // Create server channel
            IpcServerChannel channel = new IpcServerChannel("ipcU2SDLL");

            // Registratio channel
            ChannelServices.RegisterChannel(channel, false);

            // Create object and sharing
            SharedObject = new U2SSharedObject();
            SharedObject.Init(10000);
            RemotingServices.Marshal(SharedObject, "ipcRemoteObject", typeof(U2SSharedObject));
        }


        /// <summary>
        /// get integer value
        /// </summary>
        public Int32 GetIntegerValue()
        {
            return SharedObject.IntegerValue;
        }

        /// <summary>
        /// set integer value
        /// </summary>
        public void SetIntegerValue(Int32 value)
        {
            SharedObject.IntegerValue = value;
        }

        /// <summary>
        /// get float value array
        /// </summary>
        public Single[] GetFloatArray()
        {
            return SharedObject.DataArray;
        }

        /// <summary>
        /// set float value array
        /// </summary>
        public void SetFloatArray(Single[] data)
        {
            //Create clone data
            SharedObject.DataArray = (Single[])data.Clone();
        }
    }

    /// <summary>
    /// client class
    /// </summary>
    public class U2SClient
    {
        public U2SSharedObject SharedObject { get; set; }

        /// <summary>
        /// Constructor
        /// </summary>
        public U2SClient()
        {
            // Create client channel
            IpcClientChannel channel = new IpcClientChannel();

            // Registratio channel
            ChannelServices.RegisterChannel(channel, false);

            // Get remote object
            SharedObject = Activator.GetObject(typeof(U2SSharedObject), "ipc://ipcU2SDLL/ipcRemoteObject") as U2SSharedObject;
        }


        /// <summary>
        /// get integer value
        /// </summary>
        public Int32 GetIntegerValue()
        {
            return SharedObject.IntegerValue;
        }

        /// <summary>
        /// set integer value
        /// </summary>
        public void SetIntegerValue(Int32 value)
        {
            SharedObject.IntegerValue = value;
        }

        /// <summary>
        /// get float value array
        /// </summary>
        public Single[] GetFloatArray()
        {
            return SharedObject.DataArray;
        }

        /// <summary>
        /// set float value array
        /// </summary>
        public void SetFloatArray(Single[] data)
        {
            //Create clone data
            SharedObject.DataArray = (Single[])data.Clone();
        }

        public string TestDLL()
        {
            return "OK";
        }
    }
}

但是,当尝试使用Unity应用程序替换客户端应用程序时,每当我尝试访问SharedObject时都会收到错误消息。这就是Unity控制台所说的:

SerializationException: Invalid binary format
System.Runtime.Serialization.Formatters.Binary.ObjectReader.ReadRefTypeObjectInstance (System.IO.BinaryReader reader, System.Int64& objectId, System.Object& value, System.Runtime.Serialization.SerializationInfo& info) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectReader.cs:281)
System.Runtime.Serialization.Formatters.Binary.ObjectReader.ReadObject (BinaryElement element, System.IO.BinaryReader reader, System.Int64& objectId, System.Object& value, System.Runtime.Serialization.SerializationInfo& info) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectReader.cs:179)
System.Runtime.Serialization.Formatters.Binary.ObjectReader.ReadNextObject (BinaryElement element, System.IO.BinaryReader reader) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectReader.cs:130)
System.Runtime.Serialization.Formatters.Binary.ObjectReader.ReadObjectGraph (BinaryElement elem, System.IO.BinaryReader reader, Boolean readHeaders, System.Object& result, System.Runtime.Remoting.Messaging.Header[]& headers) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectReader.cs:104)
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.NoCheckDeserialize (System.IO.Stream serializationStream, System.Runtime.Remoting.Messaging.HeaderHandler handler) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/BinaryFormatter.cs:179)
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize (System.IO.Stream serializationStream) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/BinaryFormatter.cs:136)
System.Runtime.Remoting.Channels.Ipc.Win32.IpcTransport.Read (ITransportHeaders& headers, System.IO.Stream& responseStream)
System.Runtime.Remoting.Channels.Ipc.Win32.IpcClientChannelSink.ProcessMessage (IMessage msg, ITransportHeaders requestHeaders, System.IO.Stream requestStream, ITransportHeaders& responseHeaders, System.IO.Stream& responseStream)
System.Runtime.Remoting.Channels.BinaryClientFormatterSink.SyncProcessMessage (IMessage msg)

NamedPipeException: The pipe is being closed.

System.Runtime.Remoting.Channels.Ipc.Win32.NamedPipeSocket.Send (System.Byte[] buffer, Int32 offset, Int32 count)
System.Runtime.Remoting.Channels.Ipc.Win32.NamedPipeStream.Write (System.Byte[] buffer, Int32 offset, Int32 count)
System.Runtime.Remoting.Channels.Ipc.Win32.IpcTransport.Write (ITransportHeaders header, System.IO.Stream requestStream)
System.Runtime.Remoting.Channels.Ipc.Win32.IpcClientChannelSink.ProcessMessage (IMessage msg, ITransportHeaders requestHeaders, System.IO.Stream requestStream, ITransportHeaders& responseHeaders, System.IO.Stream& responseStream)
System.Runtime.Remoting.Channels.BinaryClientFormatterSink.SyncProcessMessage (IMessage msg)

每当我在dll中调用“TestDLL”函数时,我都会收到“OK”字符串,因此我假设dll已正确集成为插件。我也尝试构建为x86和x64并降级.net框架,但问题仍然存在。

您能否指出我正确的方向来解决这个问题?或者,如果您知道从非Unity应用程序向Unity App发送数据的更好方法,请告诉我们!

谢谢!

0 个答案:

没有答案