unity 共享内存 实现exe之间交互C#

适合 unity与winform  WPF之间交互,仅支持PC,使用.net4.5.2内含有的功能,在csdn上花积分学的,直接上主要代码,经测试,unity发布exe之间也可使用,unity与winform、wpf之间也可使用,前提是unity只要支持.NET 4.x的都可以使用,并定义了发送者和监听者,根据自己需求自己改吧,直接上代码:《感谢原作者,积分购买应该可以公开吧,不清除,先公开,不合适就撤,哈哈。。。》

using System;
using System.IO;
using System.IO.MemoryMappedFiles;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;

namespace ShareMemLib
{
    public class ShareMemory
    {
        private Semaphore m_Write;  //可写的信号
        private Semaphore m_Read;  //可读的信号
        private IntPtr handle;     //文件句柄
        private IntPtr addr;       //共享内存地址
        uint mapLength;            //共享内存长

        //构造函参
        string _writeMap = "WriteMap";
        string _readMap = "ReadMap";
        string _shareMemory = "shareMemory";
        string _rwsMap = "ReadMapWriteMapshareMemory";
        public delegate void RecMethod(string recMsg);
        private RecMethod _recMethod;
        private bool _isListener = false;

        #region 构造函数
        private ShareMemory() { }

        public ShareMemory(string map,bool isListener, RecMethod RecMethod = null)
        {
            if (string.IsNullOrEmpty(map))
            {
                throw new ArgumentNullException("The map can not empty");
            }
            //mapLength = 1024;
            _writeMap = map + "write";
            _readMap = map + "read";
            _shareMemory = map + "memory";
            _rwsMap = _readMap + _writeMap + _shareMemory;
            _recMethod = RecMethod;

            if (isListener)
            {
                StartListening();
                _isListener = true;
            }
        }
        ~ShareMemory()
        {
            Dispose();
        }
        #endregion

        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="msg"></param>
        public void Send(string msg)
        {
            //监听者不能发送消息,会导致监听者收到自身发送的消息
            if (_isListener)
            {
                return;
            }
            try
            {
                m_Write = Semaphore.OpenExisting(_writeMap);
                m_Read = Semaphore.OpenExisting(_readMap);
                handle = OpenFileMapping(FILE_MAP_WRITE, 0, _shareMemory);
                addr = MapViewOfFile(handle, FILE_MAP_ALL_ACCESS, 0, 0, 0);

                Write(msg);//写入信息

                m_Write.WaitOne();
                m_Read.Release();

            }
            catch (Exception ex)
            {

            }
        }
        Thread listenTh;
        /// <summary>
        /// 启动监听
        /// </summary>
        private void StartListening()
        {
            m_Write = new Semaphore(1, 1, _writeMap);//开始的时候有一个可以写
            m_Read = new Semaphore(0, 1, _readMap);//没有数据可读
            mapLength = 1024;
            IntPtr hFile = new IntPtr(INVALID_HANDLE_VALUE);
            handle = CreateFileMapping(hFile, 0, PAGE_READWRITE, 0, mapLength, _shareMemory);
            addr = MapViewOfFile(handle, FILE_MAP_ALL_ACCESS, 0, 0, 0);

            //启动监听线程
            listenTh = new Thread(() =>
            {
                while (true)
                {
                    try
                    {
                        m_Read.WaitOne();
                        m_Write.Release();
                        string recMsg = Read();
                        //触发接收消息处理方法
                        if (_recMethod != null)
                        {
                            //读取并传递接收信息
                            _recMethod(recMsg);
                        }
                    }
                    catch (Exception ex)
                    {
                        continue;
                    }
                }
            });
            listenTh.Start();
        }
        /// <summary>
        /// 读取信息
        /// </summary>
        /// <param name="mapName"></param>
        /// <param name="encoding"></param>
        private string Read(Encoding encoding = null)
        {
            long capacity = 1 << 10 << 10;
            string output = "";
            //打开共享内存   
            using (var mmf = MemoryMappedFile.OpenExisting(_rwsMap))
            {
                //使用CreateViewStream方法返回stream实例   
                using (var mmViewStream = mmf.CreateViewStream(0, capacity))
                {
                    //这里要制定Unicode编码否则会出问题   
                    using (BinaryReader rdr = new BinaryReader(mmViewStream, encoding == null ? Encoding.Unicode : encoding))
                    {
                        mmViewStream.Seek(0, SeekOrigin.Begin);
                        int length = rdr.ReadInt32();
                        char[] chars = rdr.ReadChars(length);
                        output = new string(chars);
                    }
                }
            }
            return output;
        }

        MemoryMappedFile mmf;
        MemoryMappedViewAccessor viewAccessor;
        /// <summary>
        /// 写入信息
        /// </summary>
        /// <param name="input"></param>
        private void Write(string input)
        {
            long capacity = 1 << 10 << 10;

            //创建或者打开共享内存   
            mmf = MemoryMappedFile.CreateOrOpen(_rwsMap, capacity, MemoryMappedFileAccess.ReadWrite);
            //通过MemoryMappedFile的CreateViewAccssor方法获得共享内存的访问器   
            viewAccessor = mmf.CreateViewAccessor(0, capacity);
            //向共享内存开始位置写入字符串的长度   
            viewAccessor.Write(0, input.Length);
            //向共享内存4位置写入字符   
            viewAccessor.WriteArray<char>(4, input.ToArray(), 0, input.Length);
        }

        /// <summary>
        /// 释放内存
        /// </summary>
        public void Dispose()
        {
            if (viewAccessor != null)
            {
                viewAccessor.Dispose();
            }
            if (mmf != null)
            {
                mmf.Dispose();
            }
            if (listenTh!=null)
            {
                listenTh.Abort();
            }
        }

        #region API
        const int INVALID_HANDLE_VALUE = -1;
        const int PAGE_READWRITE = 0x04;

        //共享内存
        [DllImport("Kernel32.dll", EntryPoint = "CreateFileMapping")]
        private static extern IntPtr CreateFileMapping(IntPtr hFile, //HANDLE hFile,
         UInt32 lpAttributes,//LPSECURITY_ATTRIBUTES lpAttributes,  //0
         UInt32 flProtect,//DWORD flProtect
         UInt32 dwMaximumSizeHigh,//DWORD dwMaximumSizeHigh,
         UInt32 dwMaximumSizeLow,//DWORD dwMaximumSizeLow,
         string lpName//LPCTSTR lpName
         );

        [DllImport("Kernel32.dll", EntryPoint = "OpenFileMapping")]
        private static extern IntPtr OpenFileMapping(
         UInt32 dwDesiredAccess,//DWORD dwDesiredAccess,
         int bInheritHandle,//BOOL bInheritHandle,
         string lpName//LPCTSTR lpName
         );

        const int FILE_MAP_ALL_ACCESS = 0x0002;
        const int FILE_MAP_WRITE = 0x0002;

        [DllImport("Kernel32.dll", EntryPoint = "MapViewOfFile")]
        private static extern IntPtr MapViewOfFile(
         IntPtr hFileMappingObject,//HANDLE hFileMappingObject,
         UInt32 dwDesiredAccess,//DWORD dwDesiredAccess
         UInt32 dwFileOffsetHight,//DWORD dwFileOffsetHigh,
         UInt32 dwFileOffsetLow,//DWORD dwFileOffsetLow,
         UInt32 dwNumberOfBytesToMap//SIZE_T dwNumberOfBytesToMap
         );
        [DllImport("Kernel32.dll", EntryPoint = "UnmapViewOfFile")]
        private static extern int UnmapViewOfFile(IntPtr lpBaseAddress);
        [DllImport("Kernel32.dll", EntryPoint = "CloseHandle")]
        private static extern int CloseHandle(IntPtr hObject);
        #endregion
    }
}

 

unity demo下载地址:https://download.csdn.net/download/fanglrui/18803271?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522162138754616780264098094%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fdownload.%2522%257D&request_id=162138754616780264098094&biz_id=1&utm_medium=distribute.pc_search_result.none-task-download-2~download~first_rank_v2~rank_dl_v1-2-18803271.pc_v2_rank_dl_v1&utm_term=unity%E5%85%B1%E4%BA%AB%E5%86%85%E5%AD%98demo&spm=1018.2226.3001.4451

 

  • 1
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值