在.NET中写入内存并在labview中获取进程数据

时间:2014-12-29 22:29:22

标签: c# marshalling dispose memorystream

我正在使用Kinect Face-Tracking Basics WPF示例从对象收集数据。 我可以在文本文件等中访问数据,但我想在C#进程中将数据写入托管内存,并让labview的.NET程序从同一位置获取数据。

到目前为止,这就是我所拥有的:

                    this.facePoints3D = frame.Get3DShape();

                   // using (MemoryStream stream = new MemoryStream())
                   // {
                        //var sw = new StreamWriter(stream);
                        int n = 121;
                        foreach (Vector3DF[] vector in facePoints3D.GetSlices(n))
                        {
                            //convert from float to byte array before we pass on to memory
                            var bytearray = new byte[vector.Length * this.facePoints3D.Count];
                            Buffer.BlockCopy(vector, 0, bytearray, 0, bytearray.Length);

                           //Initialize unmanaged memory to hold array.
                            int size = Marshal.SizeOf(bytearray[0]) * bytearray.Length;

                            IntPtr pnt = Marshal.AllocHGlobal(size);

                            try
                            {
                                //copy the array to unmanaged memory.
                                Marshal.Copy(bytearray, 0, pnt, bytearray.Length);

                                // Copy the unmanaged array back to another managed array.

                                byte[] bytearray2 = new byte[bytearray.Length];

                                Marshal.Copy(pnt, bytearray2, 0, bytearray.Length);

                                //Console.WriteLine("The array was coppied to unmanaged memory and back.");
                            }
                            finally
                            {
                                // Free the unmanaged memory.
                                Marshal.FreeHGlobal(pnt);
                            }

}

到目前为止,我已将labview程序正确配置为

进程A(c#):MemoryStream缓冲区 - > Marshal AllocHGlobal - >元帅副本 - > Marshal Dispose - > IntPtr ToInt64 过程B(labview):IntPtr值 - > Marshall AllocHGlobal - >元帅副本 - >目标

现在labview端运行良好,但它似乎没有从内存位置获取值。

建议吗?

1 个答案:

答案 0 :(得分:1)

这两个独立的流程吗? (2个独立的前任)。如果是这样,由于进程隔离(1进程无法看到其他进程的内存),您将无法通过直接分配共享内存。

假设您的回答是“是”(2个独立的流程),请考虑使用命名管道来传达跨流程(或将其与WCF包装)

与命名管道进行进程间通信:http://msdn.microsoft.com/en-us/library/bb546085(v=vs.110).aspx

WCF教程:基本进程间通信:http://tech.pro/tutorial/855/wcf-tutorial-basic-interprocess-communication

您还可以使用内存映射文件:http://www.abhisheksur.com/2012/02/inter-process-communication-using.html

修改

添加了使用二进制序列化程序而不是对结构进行手动内存复制的示例。您可以将生成的字节数组写入内存映射文件。此解决方案确实要求您将[Serializable]属性应用于Vector3DF结构,并且它假定读取内存的代码具有与Vector3DF相同的类型定义。

(注意:在注释中的代码中,看起来好像是在使用Vector3DF结构数组的数组,所以这就是我对序列化代码进行建模的方法。根据需要进行调整


        public byte[] SerializeVectors(Vector3DF[][] vectors)
        {
            var formatter = new BinaryFormatter();
            // note: if you are using a stream to write to the memory mapped file, 
            // you could pass it in instead of using this memory stream as an intermediary
            using (var stream = new MemoryStream())
            {
                formatter.Serialize(stream, vectors);
                return stream.ToArray();
            }
        }

        public Vector3DF[][] DeserializeVectors(byte[] vectorBuffer)
        {
            var formatter = new BinaryFormatter();
            using (var stream = new MemoryStream(vectorBuffer, false))
            {
                return (Vector3DF[][])formatter.Deserialize(stream);
            }
        }

以下是指向Gist的链接,其中包含工作代码和单元测试,以便您可以使用它:https://gist.github.com/jsmarsch/d0dcade8c656b94f5c1c