I am trying to send constantly a jagged array of floats to a Unity app from another C# application.
I got a C# dll that uses a MarshalByRefObject and opens an Ipc channel for a simple test server app and a simple test client app. Both apps are able to share data successfully. Here is the code for the 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";
}
}
}
However, when trying to substitute the client app with a Unity app, I get an error whenever I try to access the SharedObject. This is what the Unity console says:
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)
I get the "OK" string whenever I call the "TestDLL" function within the dll so I assume that the dll is correctly integrated as a plugin. I also tried building as x86 and x64 and downgrading the .net framework but the issue remains.
Could you please point me in the right direction to solve this issue? Or, if you know of a better way to send data from a non Unity App to a Unity App, please let me know!
Thank you!