2

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

我有一个 C# dll,它使用 MarshalByRefObject 并为一个简单的测试服务器应用程序和一个简单的测试客户端应用程序打开一个 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 应用程序的更好方法,请告诉我!

谢谢!

4

0 回答 0