共有メモリ・クラス

 とりあえず、ざっと作ってみました。
 かなり手抜きですが、自分用のライブラリを作るときの参考にでもどうぞ。

// ShareInfoService.h

#pragma once

using namespace System;
using namespace System::Collections::Generic;
using namespace System::IO;
using namespace System::Threading;

using namespace Microsoft::Win32::SafeHandles;

/// 
/// 共有メモリ・サービスクラス
/// 
public ref class ShareInfoService
{
private:

    // 共有メモリのシステム名称
    static String^ _share_name;

    // 排他用のシステム名称
    static String^ _access_lock;

    // データ・サイズ
    initonly DWORD _lower_size;
    initonly DWORD _upper_size;

    // アンマネージド・リソース
    //@{
    // ファイル・ハンドル
    SafeFileHandle^ _mapped_handle;

    // 共有メモリのポインタ
    IntPtr _mapped_area;
    //@}

public:

    /// 
    /// コンストラクタ
    /// 
    ShareInfoService()
    {
        this->_lower_size = 1024 * 1024;
        this->_upper_size = 0;
        this->_mapped_area = IntPtr::Zero;
        this->_mapped_handle = nullptr;
    }

    /// 
    /// メモリ・サイズを指定したコンストラクタ
    /// 
    ///  メモリ・サイズ(Byte単位) 
    ShareInfoService(long long int mem_size)
    {
        this->_lower_size = mem_size;
        this->_upper_size = mem_size >> 32;
        this->_mapped_area = IntPtr::Zero;
        this->_mapped_handle = nullptr;
    }

    /// 
    /// デストラクタ
    /// 
    ~ShareInfoService()
    {
//            Console::WriteLine("ShareInfoService::Destructor");
        ShareInfoService::!ShareInfoService();
    }

    /// 
    /// ファイナライザ
    /// 
    !ShareInfoService()
    {
//            Console::WriteLine("ShareInfoService::Finalizer");
        this->Release();
    }

    /// 
    /// 静的コンストラクタ
    /// 
    static ShareInfoService()
    {
        ShareInfoService::_share_name = "Sharable Information Service";
        ShareInfoService::_access_lock = "Mutex Write Data to Sharable Information";
    }

    /// 
    /// アンマネージド・リソースを解放するメソッド
    /// ファイナライザから呼ばれます。
    /// 
    void Release()
    {
//            Console::WriteLine("ShareInfoService::Release");
        if ( this->_mapped_area != IntPtr::Zero )
        {
            Console::WriteLine("ShareInfoService::Release : release memory.");
            ::UnmapViewOfFile( this->_mapped_area.ToPointer() );
            this->_mapped_area = IntPtr::Zero;
        }
    }

    /// 
    /// 共有メモリを作成する
    /// 
    /// 
    /// 真偽値 : メモリ作成結果を返す。
    ///        true    : エラー発生
    ///        false    : 正常終了
    /// 
    bool Create()
    {
        this->Release();

        array^ arr = ShareInfoService::_share_name->ToCharArray();
        pin_ptr ptr = &arr[0];

        bool is_created = false;

        HANDLE hMap = ::OpenFileMapping( FILE_MAP_ALL_ACCESS, FALSE, ptr);
        if ( hMap == NULL )
        {
            Console::WriteLine("ShareInfoService::Create : failed to open Mapping file.");
            String^ mut_name = "Mutex Sharable Information Service";

            Mutex^ mutex = nullptr;
            try
            {
                mutex = gcnew Mutex(false, mut_name);
            }
            catch ( UnauthorizedAccessException^ e )
            {
                Console::WriteLine("ShareInfoService::Create : no acceptant for user to create system mutex.");
            }
            catch ( IO::IOException^ e )
            {
                Console::WriteLine("ShareInfoService::Create : Win32 error.");
            }
            catch ( ApplicationException^ e )
            {
                Console::WriteLine("ShareInfoService::Create : failed to create named mutex.");
            }
            catch ( ArgumentException^ e )
            {
                Console::WriteLine("ShareInfoService::Create : Mapping Name is over 260 character.");
            }

            if ( mutex != nullptr )
            {
                if ( mutex->WaitOne(0, false) )
                {
//                        Console::WriteLine("ShareInfoService::Create : create file map.");
                    hMap = ::CreateFileMapping( (HANDLE)0xFFFFFFFF, NULL, PAGE_READWRITE,
                        this->_upper_size, this->_lower_size, ptr);

                    if ( hMap == NULL )
                    {
//                            Console::WriteLine("ShareInfoService::Create : failed to create file map.");
                        return true;
                    }
                    is_created = true;

                    mutex->ReleaseMutex();
                }
                mutex->Close();
            }
        }

        if ( hMap != NULL )
        {
//                Console::WriteLine("ShareInfoService::Create : mapping files to memory.");
            LPVOID mem = ::MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
            if ( mem != NULL )
            {
                this->_mapped_area = IntPtr(mem);
                this->_mapped_handle = gcnew SafeFileHandle(IntPtr(hMap), true);

                if ( is_created ) this->Erase();
            }
            else
            {
//                    Console::WriteLine("ShareInfoService::Create : failed to map file.");
                return true;
            }
        }
        return false;
    }

    /// 
    /// 文字列データを追加する
    /// 
    ///  キー文字列 
    ///  値 
    ///  登録データ数 
    int Append(String^ key, String^ val)
    {
        int count = 0;
        try
        {
            Mutex^ mutex = gcnew Mutex(false, ShareInfoService::_access_lock);

            if ( mutex != nullptr )
            {
                if ( mutex->WaitOne(0, false) )
                {
                    Dictionary^ param = this->Params;
                    param[key] = val;

                    MemoryStream^ mstream = gcnew MemoryStream(this->GetData());
                    BinaryWriter bwriter(mstream);

                    bwriter.Write(param->Count);

                    for each ( String^ key in param->Keys )
                    {
                        bwriter.Write(key);
                        bwriter.Write(param[key]);
                    }
                    array^ arr = mstream->ToArray();

                    pin_ptr ptr = &arr[0];
                    memcpy(this->_mapped_area.ToPointer(), ptr, this->Size);
                    mutex->ReleaseMutex();

                    count = param->Count;
                }
                mutex->Close();
            }
        }
        catch ( ApplicationException^ e )
        {
            Console::WriteLine("ShareInfoService::Create : failed to get named mutex.");
        }
        return count;
    }

#pragma region プロパティ

    /// 
    /// 共有メモリのデータサイズ
    /// 
    property long long int Size
    {
        long long int get()
        {
            if ( this->_mapped_area == IntPtr::Zero ) return 0;
            long long int size = this->_upper_size;
            size <<= 32;
            size += this->_lower_size;
            return size;
        }
    }

    /// 
    /// 実データへのアクセサ
    /// 
    property IntPtr Data
    {
        IntPtr get()
        {
            return this->_mapped_area;
        }
    }

    /// 
    /// 登録キー
    /// 
    property array^ Keys
    {
        array^ get()
        {
            MemoryStream^ mstr = gcnew MemoryStream(this->GetData());
            BinaryReader breader(mstr);
            int count = breader.ReadInt32();
            List list;
            for ( int i=0; i
    /// 登録データ
    /// 
    property Dictionary^ Params
    {
        Dictionary^ get()
        {
            MemoryStream^ mstream = gcnew MemoryStream(this->GetData());
            BinaryReader breader(mstream);
            int count = breader.ReadInt32();
            Dictionary^ data = gcnew Dictionary;
            for ( int i=0; i
    /// メモリ初期化メソッド
    /// 
    void Erase()
    {
        if ( this->_mapped_area != IntPtr::Zero )
        {
            ::memset( this->_mapped_area.ToPointer(), 0, this->Size );
        }
    }


private:

    /// 
    /// 共有メモリ上のデータをマネージドのバイト配列に変換する。
    /// 
    /// データのマネージド配列 
    array^ GetData()
    {
        if ( this->_mapped_area == IntPtr::Zero ) return nullptr;

        array^ arr = gcnew array(this->Size);
        pin_ptr ptr = &arr[0];
        memcpy(ptr, this->_mapped_area.ToPointer(), this->Size);

        return arr;
    }

    /// 
    /// マネージドなバイト配列を共有メモリに書き込む。
    /// 
    /// 
    /// 真偽値 : 処理の結果を返す。
    ///        true    : エラー発生
    ///        false    : 正常終了
    /// 
    bool PutData(array^ data)
    {
        bool result = false;
        try
        {
            Mutex^ mutex = gcnew Mutex(false, ShareInfoService::_access_lock);

            if ( mutex != nullptr )
            {
                if ( mutex->WaitOne(0, false) )
                {
                    pin_ptr ptr = &data[0];
                    memcpy(this->_mapped_area.ToPointer(), ptr, data->Length);
                    mutex->ReleaseMutex();
                }
                else
                {
                    result = true;
                }
                mutex->Close();
            }
        }
        catch ( ApplicationException^ e )
        {
//          Console::WriteLine("ShareInfoService::Create : failed to get named mutex.");
            result = true;
        }
        return result;
    }
};

 この程度なら問題ないんだけどなぁ。
 サービス化を考えると難しい。