読者です 読者をやめる 読者になる 読者になる

ttp://ameblo.jp/pink-green-onion/から拝借、ちょこっと修正してアップしました。 (Syntax hiligterで書いとかないと、業務用パソコンでコピーした後にひと手間かかるので...)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
 
namespace TestShareMemory
{
    public class SharedMemoryMgr
    {
        ////////////////////////////////////////////////////// 
        // 使用するAPIC#用にマーシャリングして再定義
        // http://www.pinvoke.net/index.aspx 
        ////////////////////////////////////////////////////// 
 
        //==========================
        // アクセス制限設定等
        //==========================
        const UInt32 STANDARD_RIGHTS_REQUIRED = 0x000F0000;
        const UInt32 SECTION_QUERY = 0x0001;
        const UInt32 SECTION_MAP_WRITE = 0x0002;
        const UInt32 SECTION_MAP_READ = 0x0004;
        const UInt32 SECTION_MAP_EXECUTE = 0x0008;
        const UInt32 SECTION_EXTEND_SIZE = 0x0010;
        const UInt32 SECTION_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | SECTION_QUERY |
        SECTION_MAP_WRITE |
        SECTION_MAP_READ |
        SECTION_MAP_EXECUTE |
        SECTION_EXTEND_SIZE);
        const UInt32 FILE_MAP_ALL_ACCESS = SECTION_ALL_ACCESS;
        const UInt32 PAGE_READWRITE = 4;
 
        //==========================
        // DLLImport
        //==========================
        [DllImport("kernel32.dll", SetLastError = true)]
        static extern IntPtr CreateFileMapping(UIntPtr hFile,
        IntPtr lpFileMappingAttributes, uint flProtect, uint dwMaximumSizeHigh,
        uint dwMaximumSizeLow, string lpName);
 
        [System.Runtime.InteropServices.DllImport("Kernel32")]
        public static extern IntPtr CreateFileMapping(IntPtr hFile,
            IntPtr pAttributes, UInt32 flProtect,
            UInt32 dwMaximumSizeHigh, UInt32 dwMaximumSizeLow, String pName);
 
        [DllImport("kernel32.dll", SetLastError = true)]
        static extern IntPtr MapViewOfFile(IntPtr hFileMappingObject, uint
        dwDesiredAccess, uint dwFileOffsetHigh, uint dwFileOffsetLow,
        uint dwNumberOfBytesToMap);
 
        [DllImport("kernel32.dll")]
        static extern void CopyMemory(IntPtr Destination, IntPtr Source, uint Length);
 
        [DllImport("kernel32.dll")]
        static extern bool UnmapViewOfFile(IntPtr lpBaseAddress);
 
        [DllImport("kernel32.dll")]
        static extern bool CloseHandle(IntPtr hObject);
 
        ////////////////////////////////////////////////
        // 定数
        ////////////////////////////////////////////////
        //すでに共有メモリ作成済の場合のエラー値 
        const int ERROR_ALREADY_EXISTS = 183;
 
        ////////////////////////////////////////////////
        // 構造体
        ////////////////////////////////////////////////
        //テスト用の共有データ型 
        public struct SharedData
        {
            public int m_iData1;
            public int m_iData2;
            public int m_iData3;
        }
 
        ////////////////////////////////////////////////
        // メンバ変数
        ////////////////////////////////////////////////
        //共有メモリ確保用のハンドルとポインタを定義 
        private IntPtr m_memAreaHandle = IntPtr.Zero;
        private IntPtr m_memAreaPointer = IntPtr.Zero;
 
        //共有メモリへのアクセス用排他ミューテックス
        private Mutex m_Mutex;
 
        ////////////////////////////////////////////////
        // メンバ関数
        ////////////////////////////////////////////////
        //==========================
        // コンストラクタ
        //==========================
        public SharedMemoryMgr()
        {
            // ミューテックスを作成
            m_Mutex = new System.Threading.Mutex(false, "ComonMemMutex");
        }
 
        //==========================
        // デストラクタ
        //==========================
        ~SharedMemoryMgr()
        {
            if (m_memAreaPointer != IntPtr.Zero)
            {
                UnmapViewOfFile(m_memAreaPointer);
                m_memAreaPointer = IntPtr.Zero;
            }
 
            if (m_memAreaHandle != IntPtr.Zero)
            {
                CloseHandle(m_memAreaHandle);
                m_memAreaHandle = IntPtr.Zero;
            }
        }
 
        //=====================================
        // 共有メモリ作成
        // 戻り値 true:成功 false:失敗
        //=====================================
        public unsafe bool CreateMemory()
        {
            try
            {
                IntPtr InvalidHandleValue = new IntPtr(-1);
 
                m_memAreaHandle = CreateFileMapping(InvalidHandleValue, // ファイルハンドル 
                IntPtr.Zero, // セキュリティ属性 
                PAGE_READWRITE, // 保護属性(R/W) 
                0, // サイズ上位 
                1024, // サイズ下位 
                "CommonMem"); // オブジェクト名 
 
                // マッピング処理
                m_memAreaPointer = MapViewOfFile(m_memAreaHandle, SECTION_ALL_ACCESS, 0, 0, 0);
 
                int retval = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
                if (retval != ERROR_ALREADY_EXISTS)
                {
                    //エリア初期化処理など
                }
            }
            catch (Exception ex)
            {
                ex.ToString();
            }
            return false;
        }
 
        //=====================================
        // 共有メモリに文字列を書込む
        // <Param> 
        // strText 文字列
        // <Return> true:成功 false:失敗
        //=====================================
        public void WriteMemory(string strText)
        {
            //排他制御 ミューテックス取得 
            m_Mutex.WaitOne(Timeout.Infinite, true);
 
            // stringをIntPtrへ変換 ※この時メモリを確保するので、後でFreeCoTaskMemすること!!
            IntPtr ptrTemp = Marshal.StringToHGlobalUni(strText);
            CopyMemory(m_memAreaPointer, ptrTemp, (uint)(((int)strText.Length) 
                * Marshal.SizeOf(typeof(IntPtr))));
            Marshal.FreeCoTaskMem(ptrTemp);
 
            //ミューテックス解放
            m_Mutex.ReleaseMutex();
        }
 
        //=====================================
        // 共有メモリより文字列を読込む
        // <Return> 文字列
        //=====================================
        public string ReadMemory()
        {
            string strText;
            //排他制御 ミューテックス取得 
            m_Mutex.WaitOne(Timeout.Infinite, true);
            //共有メモリのunmanagedメモリよりmanagedデータへ変換して文字列へコピー
            strText = System.Runtime.InteropServices.Marshal.PtrToStringUni(m_memAreaPointer);
            //ミューテックス解放
            m_Mutex.ReleaseMutex();
            return strText;
        }
 
        //=====================================
        // 共有メモリに構造体データを書込む
        // <Param> 
        // strText 構造体データ
        //=====================================
        public void WriteMemoryData(SharedData SharedData)
        {
            //排他制御 ミューテックス取得 
            m_Mutex.WaitOne(Timeout.Infinite, true);
            Marshal.StructureToPtr(SharedData, m_memAreaPointer, true);
            //ミューテックス解放
            m_Mutex.ReleaseMutex();
        }
 
        //=====================================
        // 共有メモリより構造体データを読込む
        // <Param> 
        // strText 構造体データ参照
        //=====================================
        public void ReadMemoryData(out SharedData SharedData)
        {
            //排他制御 ミューテックス取得 
            m_Mutex.WaitOne(Timeout.Infinite, true);
            object obj = Marshal.PtrToStructure(m_memAreaPointer, typeof(SharedData));
            //ミューテックス解放
            m_Mutex.ReleaseMutex();
 
            SharedData = (SharedData)obj;
        }
    }
}