■
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 { ////////////////////////////////////////////////////// // 使用するAPIをC#用にマーシャリングして再定義 // 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; } } }