二禁荸、PC集成unity(3)共享內(nèi)存方式通信

unity端
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;  //可寫(xiě)的信號(hào)
        private Semaphore m_Read;  //可讀的信號(hào)
        private IntPtr handle;     //文件句柄
        private IntPtr addr;       //共享內(nèi)存地址
        //uint mapLength = 400000;            //共享內(nèi)存長(zhǎng)
        uint mapLength = 4940860;            //共享內(nèi)存長(zhǎng)

        //構(gòu)造函參
        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 構(gòu)造函數(shù)
        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>
        /// 發(fā)送消息
        /// </summary>
        /// <param name="msg"></param>
        public void Send(string msg)
        {
            //監(jiān)聽(tīng)者不能發(fā)送消息熄云,會(huì)導(dǎo)致監(jiān)聽(tīng)者收到自身發(fā)送的消息
            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);//寫(xiě)入信息

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

            }
            catch (Exception ex)
            {

            }
        }
        Thread listenTh;
        /// <summary>
        /// 啟動(dòng)監(jiān)聽(tīng)
        /// </summary>
        private void StartListening()
        {
            m_Write = new Semaphore(1, 1, _writeMap);//開(kāi)始的時(shí)候有一個(gè)可以寫(xiě)
            m_Read = new Semaphore(0, 1, _readMap);//沒(méi)有數(shù)據(jù)可讀
            //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);

            //啟動(dòng)監(jiān)聽(tīng)線程
            listenTh = new Thread(() =>
            {
                while (true)
                {
                    try
                    {
                        m_Read.WaitOne();
                        m_Write.Release();
                        string recMsg = Read();
                        //觸發(fā)接收消息處理方法
                        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 = "";
            //打開(kāi)共享內(nèi)存   
            using (var mmf = MemoryMappedFile.OpenExisting(_rwsMap))
            {
                //使用CreateViewStream方法返回stream實(shí)例   
                using (var mmViewStream = mmf.CreateViewStream(0, capacity))
                {
                    //這里要制定Unicode編碼否則會(huì)出問(wèn)題   
                    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>
        /// 寫(xiě)入信息
        /// </summary>
        /// <param name="input"></param>
        private void Write(string input)
        {
            long capacity = 1 << 10 << 10;

            //創(chuàng)建或者打開(kāi)共享內(nèi)存   
            mmf = MemoryMappedFile.CreateOrOpen(_rwsMap, capacity, MemoryMappedFileAccess.ReadWrite);
            //通過(guò)MemoryMappedFile的CreateViewAccssor方法獲得共享內(nèi)存的訪問(wèn)器   
            viewAccessor = mmf.CreateViewAccessor(0, capacity);
            //向共享內(nèi)存開(kāi)始位置寫(xiě)入字符串的長(zhǎng)度   
            viewAccessor.Write(0, input.Length);
            //向共享內(nèi)存4位置寫(xiě)入字符   
            viewAccessor.WriteArray<char>(4, input.ToArray(), 0, input.Length);
        }

        /// <summary>
        /// 釋放內(nèi)存
        /// </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;

        //共享內(nèi)存
        [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
    }
}

這里開(kāi)辟了多個(gè)共享內(nèi)存,實(shí)際情況看需要挺邀。

另一端
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;  //可寫(xiě)的信號(hào)
        private Semaphore m_Read;  //可讀的信號(hào)
        private IntPtr handle;     //文件句柄
        private IntPtr addr;       //共享內(nèi)存地址
        uint mapLength = 4940860;            //共享內(nèi)存長(zhǎng)

        //構(gòu)造函參
        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;

        private int ptrTemp = -1;

        #region 構(gòu)造函數(shù)
        private ShareMemory() { }

        public ShareMemory(string map, bool isListener, RecMethod RecMethod = null, int ptr = 0)
        {
            if (string.IsNullOrEmpty(map))
            {
                throw new ArgumentNullException("The map can not empty");
            }
            if (handle != null)
            {
                ptrTemp = ptr;
            }
            //mapLength = 1920 * 1080;
            _writeMap = map + "write";
            _readMap = map + "read";
            _shareMemory = map + "memory";
            _rwsMap = _readMap + _writeMap + _shareMemory;
            _recMethod = RecMethod;

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

        /// <summary>
        /// 發(fā)送消息
        /// </summary>
        /// <param name="msg"></param>
        public void Send(string msg)
        {
            //監(jiān)聽(tīng)者不能發(fā)送消息,會(huì)導(dǎo)致監(jiān)聽(tīng)者收到自身發(fā)送的消息
            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);//寫(xiě)入信息

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

            }
            catch (Exception ex)
            {

            }
        }
        Thread listenTh;
        /// <summary>
        /// 啟動(dòng)監(jiān)聽(tīng)
        /// </summary>
        private void StartListening()
        {
            m_Write = new Semaphore(1, 1, _writeMap);//開(kāi)始的時(shí)候有一個(gè)可以寫(xiě)
            m_Read = new Semaphore(0, 1, _readMap);//沒(méi)有數(shù)據(jù)可讀
            //mapLength = 1920 * 1080;
            //IntPtr hFile = new IntPtr(INVALID_HANDLE_VALUE);
            IntPtr hFile = new IntPtr(ptrTemp);
            handle = CreateFileMapping(hFile, 0, PAGE_READWRITE, 0, mapLength, _shareMemory);
            addr = MapViewOfFile(handle, FILE_MAP_ALL_ACCESS, 0, 0, 0);

            //啟動(dòng)監(jiān)聽(tīng)線程
            listenTh = new Thread(() =>
            {
                while (true)
                {
                    try
                    {
                        m_Read.WaitOne();
                        m_Write.Release();
                        string recMsg = Read();
                        //觸發(fā)接收消息處理方法
                        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 = "";
            //打開(kāi)共享內(nèi)存   
            using (var mmf = MemoryMappedFile.OpenExisting(_rwsMap))
            {
                //使用CreateViewStream方法返回stream實(shí)例   
                using (var mmViewStream = mmf.CreateViewStream(0, capacity))
                {
                    //這里要制定Unicode編碼否則會(huì)出問(wèn)題   
                    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>
        /// 寫(xiě)入信息
        /// </summary>
        /// <param name="input"></param>
        private void Write(string input)
        {
            long capacity = 1 << 10 << 10;

            //創(chuàng)建或者打開(kāi)共享內(nèi)存   
            mmf = MemoryMappedFile.CreateOrOpen(_rwsMap, capacity, MemoryMappedFileAccess.ReadWrite);
            //通過(guò)MemoryMappedFile的CreateViewAccssor方法獲得共享內(nèi)存的訪問(wèn)器   
            viewAccessor = mmf.CreateViewAccessor(0, capacity);
            //向共享內(nèi)存開(kāi)始位置寫(xiě)入字符串的長(zhǎng)度   
            viewAccessor.Write(0, input.Length);
            //向共享內(nèi)存4位置寫(xiě)入字符   
            viewAccessor.WriteArray<char>(4, input.ToArray(), 0, input.Length);
        }

        /// <summary>
        /// 釋放內(nèi)存
        /// </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;

        //共享內(nèi)存
        [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
    }
}

實(shí)際是一模一樣的

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末跳座,一起剝皮案震驚了整個(gè)濱河市端铛,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌疲眷,老刑警劉巖沦补,帶你破解...
    沈念sama閱讀 219,490評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異咪橙,居然都是意外死亡夕膀,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門美侦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)产舞,“玉大人,你說(shuō)我怎么就攤上這事菠剩∫酌ǎ” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,830評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵具壮,是天一觀的道長(zhǎng)准颓。 經(jīng)常有香客問(wèn)我,道長(zhǎng)棺妓,這世上最難降的妖魔是什么攘已? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,957評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮怜跑,結(jié)果婚禮上样勃,老公的妹妹穿的比我還像新娘。我一直安慰自己性芬,他們只是感情好峡眶,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,974評(píng)論 6 393
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著植锉,像睡著了一般辫樱。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上俊庇,一...
    開(kāi)封第一講書(shū)人閱讀 51,754評(píng)論 1 307
  • 那天狮暑,我揣著相機(jī)與錄音鸡挠,去河邊找鬼。 笑死心例,一個(gè)胖子當(dāng)著我的面吹牛宵凌,可吹牛的內(nèi)容都是我干的鞋囊。 我是一名探鬼主播止后,決...
    沈念sama閱讀 40,464評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼溜腐!你這毒婦竟也來(lái)了译株?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤挺益,失蹤者是張志新(化名)和其女友劉穎歉糜,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體望众,經(jīng)...
    沈念sama閱讀 45,847評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡匪补,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,995評(píng)論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了烂翰。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片夯缺。...
    茶點(diǎn)故事閱讀 40,137評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖甘耿,靈堂內(nèi)的尸體忽然破棺而出踊兜,到底是詐尸還是另有隱情,我是刑警寧澤佳恬,帶...
    沈念sama閱讀 35,819評(píng)論 5 346
  • 正文 年R本政府宣布捏境,位于F島的核電站,受9級(jí)特大地震影響毁葱,放射性物質(zhì)發(fā)生泄漏垫言。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,482評(píng)論 3 331
  • 文/蒙蒙 一倾剿、第九天 我趴在偏房一處隱蔽的房頂上張望骏掀。 院中可真熱鬧,春花似錦柱告、人聲如沸截驮。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,023評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)葵袭。三九已至,卻和暖如春乖菱,著一層夾襖步出監(jiān)牢的瞬間坡锡,已是汗流浹背蓬网。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,149評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留鹉勒,地道東北人帆锋。 一個(gè)月前我還...
    沈念sama閱讀 48,409評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像禽额,于是被迫代替她去往敵國(guó)和親锯厢。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,086評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • unity 端代碼 PC 端代碼或另一端unity 注意:支持Unity和Unity互通,也支持Unity和PC程序互通
    GameObjectLgy閱讀 238評(píng)論 0 0
  • ?通信是Android開(kāi)發(fā)必不可少的一部分藻丢,不管是我們做應(yīng)用App開(kāi)發(fā)剪撬,還是Android系統(tǒng),都使用了大量的通信...
    子者不語(yǔ)閱讀 416評(píng)論 0 1
  • 作者丨二營(yíng)長(zhǎng)的意大利炮手 鏈接: https://juejin.im/post/5d7efce9f265da03a...
    darkness605閱讀 327評(píng)論 0 0
  • 這是一篇關(guān)于進(jìn)程間通信的文章 轉(zhuǎn)載整理至 http://www.cnblogs.com/wcadaydayup/p...
    10d3642f94b1閱讀 1,329評(píng)論 0 3
  • 進(jìn)程間通信 引言 在操作系統(tǒng)中悠反,一個(gè)進(jìn)程可以理解為是關(guān)于計(jì)算機(jī)資源集合的一次運(yùn)行活動(dòng)残黑,其就是一個(gè)正在執(zhí)行的程序的實(shí)...
    我是真ikun閱讀 613評(píng)論 0 0