原文 C#共享内存类改进版

改进说明及源码实例下载见:http://blog.csdn.net/zzh8845/archive/2008/11/22/3349963.aspx

ShareMem.cs

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Threading;
using System.IO;

namespace ShareMemLib
{
    public class ShareMem
    {
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, IntPtr lParam);

[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr CreateFileMapping(int hFile, IntPtr lpAttributes, uint flProtect, uint dwMaxSizeHi, uint dwMaxSizeLow, string lpName);

[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr OpenFileMapping(int dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, string lpName);

[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr MapViewOfFile(IntPtr hFileMapping, uint dwDesiredAccess, uint dwFileOffsetHigh, uint dwFileOffsetLow, uint dwNumberOfBytesToMap);

[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
        public static extern bool UnmapViewOfFile(IntPtr pvBaseAddress);

[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
        public static extern bool CloseHandle(IntPtr handle);

[DllImport("kernel32", EntryPoint = "GetLastError")]
        public static extern int GetLastError();

const int ERROR_ALREADY_EXISTS = 183;

const int FILE_MAP_COPY = 0x0001;
        const int FILE_MAP_WRITE = 0x0002;
        const int FILE_MAP_READ = 0x0004;
        const int FILE_MAP_ALL_ACCESS = 0x0002 | 0x0004;

const int PAGE_READONLY = 0x02;
        const int PAGE_READWRITE = 0x04;
        const int PAGE_WRITECOPY = 0x08;
        const int PAGE_EXECUTE = 0x10;
        const int PAGE_EXECUTE_READ = 0x20;
        const int PAGE_EXECUTE_READWRITE = 0x40;

const int SEC_COMMIT = 0x8000000;
        const int SEC_IMAGE = 0x1000000;
        const int SEC_NOCACHE = 0x10000000;
        const int SEC_RESERVE = 0x4000000;

const int INVALID_HANDLE_VALUE = -1;

IntPtr m_hSharedMemoryFile = IntPtr.Zero;
        IntPtr m_pwData = IntPtr.Zero;
        IntPtr m_pwDataWrite = IntPtr.Zero;
        IntPtr m_pwDataRead = IntPtr.Zero;
        bool m_bAlreadyExist = false;
        bool m_bInit = false;
        long m_MemSize = 0;
        int m_length = 0;
        int m_count = 0;
        const int infoSize = 50;
        Semaphore semRead;
        Semaphore semWrite;
        Semaphore semWriteLength;
        String m_pathMSGCSV = "Messages.csv";

public ShareMem()
        {
        }
        ~ShareMem()
        {
            Close();
        }

/// 
        /// 初始化共享内存
        /// 
        /// 共享内存名称
        /// 共享内存大小
        /// 
        public int Init(string strName, long lngSize)
        {
            if (lngSize <= 0 || lngSize > 0x00800000) lngSize = 0x00800000;
            m_MemSize = lngSize;
            if (strName.Length > 0)
            {
                //创建内存共享体(INVALID_HANDLE_VALUE)
                m_hSharedMemoryFile = CreateFileMapping(INVALID_HANDLE_VALUE, IntPtr.Zero, (uint)PAGE_READWRITE, 0, (uint)lngSize, strName);

if (GetLastError() == ERROR_ALREADY_EXISTS) //已经创建
                {
                    m_bAlreadyExist = true;
                    m_hSharedMemoryFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, false, strName);
                }

if (m_hSharedMemoryFile == IntPtr.Zero)
                {
                    m_bAlreadyExist = false;
                    m_bInit = false;
                    return 2; //创建共享体失败
                }
                else
                {
                    if (GetLastError() == ERROR_ALREADY_EXISTS) //已经创建
                    {
                        m_bAlreadyExist = true;
                    }
                    else                                         //新创建
                    {
                        m_bAlreadyExist = false;
                    }
                }
                //---------------------------------------
                //创建内存映射
                m_pwData = MapViewOfFile(m_hSharedMemoryFile, FILE_MAP_ALL_ACCESS, 0, 0, (uint)lngSize);
                m_pwDataWrite = m_pwData;
                m_pwDataRead = (IntPtr)(m_pwData.GetHashCode() + infoSize);
                if (m_pwData == IntPtr.Zero)
                {
                    m_bInit = false;
                    CloseHandle(m_hSharedMemoryFile);
                    return 3; //创建内存映射失败
                }
                else
                {
                    m_bInit = true;
                    if (m_bAlreadyExist == false)
                    {
                        //初始化
                    }
                }
                //----------------------------------------
            }
            else
            {
                return 1; //参数错误     
            }

SetSemaphore();
            if (m_bAlreadyExist == false)
            {
                WriteLengthAndCount(0, 0);
            }
            return 0;     //创建成功
        }

/// 
        /// 关闭共享内存
        /// 
        public void Close()
        {
            if (m_bInit)
            {
                UnmapViewOfFile(m_pwData);
                CloseHandle(m_hSharedMemoryFile);
            }
        }

public bool SetSemaphore()
        {
            try
            {
                semRead = Semaphore.OpenExisting("ReadShareMemory");
                semWrite = Semaphore.OpenExisting("WriteShareMemory");
                semWriteLength = Semaphore.OpenExisting("WriteLengthShareMemory");
            }
            catch (Exception)
            {
                semRead = new Semaphore(0, 1, "ReadShareMemory");
                semWrite = new Semaphore(1, 1, "WriteShareMemory");
                semWriteLength = new Semaphore(1, 1, "WriteLengthShareMemory");
            }
            return true;
        }

/**
        public int ReadLength()
        {
            Byte[] bytData = new Byte[infoSize];
            if (infoSize > m_MemSize) return 2; //超出数据区
            if (m_bInit)
            {
                Marshal.Copy(m_pwData, bytData, 0, infoSize);
            }
            else
            {
                return 1; //共享内存未初始化
            }
            String str = System.Text.Encoding.Unicode.GetString(bytData).Trim('/0');
            m_length = System.Convert.ToInt32(str);
            return 0;     //读成功
        }

public int WriteLength(int length)
        {
            semWriteLength.WaitOne();
            if (infoSize > m_MemSize) return 2; //超出数据区
            String strLength = System.Convert.ToString(length);
            Byte[] bytData = System.Text.Encoding.Unicode.GetBytes(strLength);
            if (m_bInit)
            {
                Marshal.Copy(bytData, 0, m_pwData, bytData.Length);
            }
            else
            {
                semWriteLength.Release();
                return 1; //共享内存未初始化
            }
            semWriteLength.Release();
            return 0;
        }
        **/

public int ReadLengthAndCount()
        {
            Byte[] bytData = new Byte[infoSize];
            if (infoSize > m_MemSize) return 2; //超出数据区
            if (m_bInit)
            {
                Marshal.Copy(m_pwData, bytData, 0, infoSize);
            }
            else
            {
                return 1; //共享内存未初始化
            }
            String str = System.Text.Encoding.Unicode.GetString(bytData).Trim('/0');
            String[] strs = System.Text.RegularExpressions.Regex.Split(str, "/0");
            m_length = System.Convert.ToInt32(strs[0]);
            m_count = System.Convert.ToInt32(strs[1]);
            return 0;     //读成功
        }

public int WriteLengthAndCount(int length, int count)
        {
            semWriteLength.WaitOne();
            if (infoSize > m_MemSize) return 2; //超出数据区
            String strLengthAndCount = System.Convert.ToString(length) + "/0" + System.Convert.ToString(count);
            Byte[] bytData = System.Text.Encoding.Unicode.GetBytes(strLengthAndCount);
            if (m_bInit)
            {
                /**
                Byte[] byteZero = new Byte[infoSize];
                for (int i = 0; i < infoSize; i++)
                {
                    byteZero[i] = (Byte)'/0';
                }
                Marshal.Copy(byteZero, 0, m_pwData, infoSize);
                 * **/
                Marshal.Copy(bytData, 0, m_pwData, bytData.Length);
            }
            else
            {
                semWriteLength.Release();
                return 1; //共享内存未初始化
            }
            semWriteLength.Release();
            return 0;
        }

/// 
        /// 读数据
        /// 
        /// 数据
        /// 起始地址
        /// 个数
        /// 
        public int Read(ref byte[] bytData)
        {
            ReadLengthAndCount();
            if (m_length > m_MemSize) return 2; //超出数据区
            if (m_bInit)
            {
                Marshal.Copy(m_pwDataRead, bytData, 0, m_length);
            }
            else
            {
                return 1; //共享内存未初始化
            }
            return 0;     //读成功
        }

/// 
        /// 写数据
        /// 
        /// 数据
        /// 起始地址
        /// 个数
        /// 
        public int Write(byte[] bytData, int lngSize)
        {
            semWrite.WaitOne();
            ReadLengthAndCount();
            if (m_length + lngSize > m_MemSize)
            {
                System.Windows.Forms.MessageBox.Show("Share memory is full. " + (m_length + lngSize) + ">" + m_MemSize);
                semWrite.Release();
                return 2; //超出数据区
            }
            if (m_bInit)
            {
                m_pwDataWrite = (IntPtr)(m_pwData.GetHashCode() + m_length + infoSize);
                Marshal.Copy(bytData, 0, m_pwDataWrite, lngSize);
                m_length += lngSize;
                m_count++;
            }
            else
            {
                semWrite.Release();
                return 1; //共享内存未初始化
            }
            WriteLengthAndCount(m_length, m_count);
            semWrite.Release();
            return 0;     //写成功
        }

public int GetLength()
        {
            ReadLengthAndCount();
            return this.m_length;
        }

public int GetCount()
        {
            ReadLengthAndCount();
            return this.m_count;
        }

public int ReadCSV()
        {
            try
            {
                if (!File.Exists(m_pathMSGCSV))
                    File.CreateText(m_pathMSGCSV).Close();

StreamReader sr = System.IO.File.OpenText(m_pathMSGCSV);
                while (!sr.EndOfStream)
                {
                    String strLine = sr.ReadLine();
                    if (!System.String.IsNullOrEmpty(strLine))
                    {
                        strLine += "/0";
                        Byte[] data = System.Text.Encoding.Unicode.GetBytes(strLine);
                        Write(data, data.Length);
                    }
                }
                sr.Close();
            }
            catch (Exception e)
            {
                System.Windows.Forms.MessageBox.Show("Error:ReadCSV()" + e);
                return 1;
            }
            return 0;
        }

public int WriteCSV()
        {
            try
            {
                StreamWriter sw = System.IO.File.AppendText(m_pathMSGCSV);
                ReadLengthAndCount();
                Byte[] btydata = new Byte[m_length];
                Read(ref btydata);
                String strOut = System.Text.Encoding.Unicode.GetString(btydata).Trim('/0');
                String[] sArray = System.Text.RegularExpressions.Regex.Split(strOut, "/0");
                foreach (String str in sArray)
                {
                    if (!String.IsNullOrEmpty(str))
                        sw.WriteLine(str);
                }
                sw.Flush();
                sw.Close();
            }
            catch (Exception)
            {
                System.Windows.Forms.MessageBox.Show("Error:WriteCSV()");
                return 1;
            }
            return 0;
        }

public int Clear()
        {
            ReadLengthAndCount();
            if (infoSize + m_length > m_MemSize) return 2; //超出数据区
            if (m_bInit)
            {
                Byte[] byteZero = new Byte[infoSize + m_length];
                for (int i = 0; i < infoSize; i++)
                {
                    byteZero[i] = (Byte)'/0';
                }
                Marshal.Copy(byteZero, 0, m_pwData, infoSize + m_length);
                m_pwDataWrite = m_pwData;
                m_length = 0;
                m_count = 0;
                WriteLengthAndCount(0, 0);
            }
            return 0;
        }
    }
}

Form1.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ShareMemLib;

namespace ShareMemory
{
    public partial class frmMain : Form
    {
        ShareMem MemDB = new ShareMem();
        const int m_memSize = 4096000;

public frmMain()
        {
            InitializeComponent();
            btnInit.Enabled = true;
            btnWrite.Enabled = false;
            btnRead.Enabled = false;
            txtInput.Text = "AAA";
        }

private void ReadTest()
        {
            String str = ReadToStr();
            String[] strArray = System.Text.RegularExpressions.Regex.Split(str, "/0");
            lstData.Items.Clear();
            foreach (String s in strArray)
            {
                lstData.Items.Add(s);
            }
        }

private String ReadToStr()
        {
            int currentLength = MemDB.GetLength();
            int currentCount = MemDB.GetCount();
            Byte[] data = new Byte[currentLength];
            MemDB.Read(ref data);
            lblUsedSize.Text = currentLength.ToString();
            lblCount.Text = currentCount.ToString();
            return System.Text.Encoding.Unicode.GetString(data);
        }

private void WriteStr(String str)
        {
            btnWrite.Enabled = false;
            try
            {
                Byte[] data = System.Text.Encoding.Unicode.GetBytes(str);
                MemDB.Write(data, data.Length);
            }
            catch (Exception)
            {
                MessageBox.Show("Error in WriteStr");
            }
            btnWrite.Enabled = true;
        }

private void btnInit_Click(object sender, EventArgs e)
        {
            if (MemDB.Init("YFMemTest", m_memSize) != 0)
            {
                //初始化失败
                MessageBox.Show("初始化失败");
            }
            else
            {
                btnInit.Enabled = false;
                btnWrite.Enabled = true;
                btnRead.Enabled = true;
            }
            lblTotalSize.Text = m_memSize.ToString();
        }

private void btnClear_Click(object sender, EventArgs e)
        {
            MemDB.Clear();
            ReadTest();
        }

private void btnReadCSV_Click(object sender, EventArgs e)
        {
            MemDB.ReadCSV();
            ReadTest();
        }

private void btnWriteCSV_Click(object sender, EventArgs e)
        {
            MemDB.WriteCSV();
            MemDB.Clear();
            ReadTest();
        }

private void btnRead_Click(object sender, EventArgs e)
        {
            ReadTest();
        }

private void btnWrite_Click(object sender, EventArgs e)
        {
            //String str = "B000" + (i++) + ",1,1,2008,success/0";
            String str = txtInput.Text + System.DateTime.Now.ToString(",yyyMMdd,HHmmss,fff/0");
            WriteStr(str);

ReadTest();
        }
    }
}

C#共享内存类改进版的更多相关文章

  1. C#共享内存实例 附源码

    原文 C#共享内存实例 附源码 网上有C#共享内存类,不过功能太简单了,并且写内存每次都从开头写.故对此进行了改进,并做了个小例子,供需要的人参考. 主要改进点: 通过利用共享内存的一部分空间(以下称 ...

  2. Boost:shared_memory_object --- 共享内存

    什么是共享内存 共享内存是最快速的进程间通信机制.操作系统在几个进程的地址空间上映射一段内存,然后这几个进程可以在不需要调用操作系统函数的情况下在那段内存上进行读/写操作.但是,在进程读写共享内存时, ...

  3. 共享内存操作类(C#源码)

    原文 http://blog.csdn.net/yefanqiu/article/details/1717458 VC++的共享内存操作代码实现起来相对比较容易,但是用C#语言来实现,就有一定难度,由 ...

  4. PHP共享内存yac操作类

    http://www.laruence.com/2013/03/18/2846.html   鸟哥介绍 https://www.cnblogs.com/willamwang/p/8918377.htm ...

  5. php操作共享内存shmop类及简单使用测试(代码)

    SimpleSHM 是一个较小的抽象层,用于使用 PHP 操作共享内存,支持以一种面向对象的方式轻松操作内存段.在编写使用共享内存进行存储的小型应用程序时,这个库可帮助创建非常简洁的代码.可以使用 3 ...

  6. 撸代码--类QQ聊天实现(基于linux 管道 信号 共享内存)

    一:任务描写叙述 A,B两个进程通过管道通信,像曾经的互相聊天一样,然后A进程每次接收到的数据通过A1进程显示(一个新进程,用于显示A接收到的信息),A和A1间的数据传递採用共享内存,相应的有一个B1 ...

  7. OpenMP共享内存并行编程详解

    实验平台:win7, VS2010 1. 介绍 平行计算机可以简单分为共享内存和分布式内存,共享内存就是多个核心共享一个内存,目前的PC就是这类(不管是只有一个多核CPU还是可以插多个CPU,它们都有 ...

  8. java 并发性和多线程 -- 读感 (二 线程间通讯,共享内存的机制)

    参考文章:http://ifeve.com/java-concurrency-thread-directory/ 其中的竞态,线程安全,内存模型,线程间的通信,java ThreadLocal类小节部 ...

  9. Linux IPC POSIX 共享内存

    模型 #include <unistd.h> //for fstat() #include <sys/types.h> //for fstat() #include <s ...

随机推荐

  1. 日期选择器——java

    转载:http://zgdeng.iteye.com/blog/1405650 代码如下: import java.awt.BasicStroke; import java.awt.BorderLay ...

  2. This project references NuGet package(s) that are missing on this computer.

    Install Nuget. Right click on the solution and select "Enable NuGet Package Restore". Clic ...

  3. 手机root初体验

    看到别人写的一些自己想知道的东西,顿时感到很有兴趣也很强大,固然做一个牛人有很多小粉丝是无比崇高的,可去往牛人的路上也不能少了自己~加油! 一 我来解释一下什么是ROOT以及原理 是不是要ROOT,是 ...

  4. 转载 LayoutInflater的inflate函数用法详解

    http://www.open-open.com/lib/view/open1328837587484.html LayoutInflater的inflate函数用法详解 LayoutInflater ...

  5. IOS基础:深入理解Objective-c中@class的含义

    objective-c中,当一个类使用到另一个类时,并且在类的头文件中需要创建被引用的指针时, 如下面代码: A.h文件 #import "B.h" @interface A :  ...

  6. Control的Invoke和BeginInvoke详解

    (一)Control的Invoke和BeginInvoke 我们要基于以下认识: (1)Control的Invoke和BeginInvoke与Delegate的Invoke和BeginInvoke是不 ...

  7. JS中的this都有什么作用?

    1.全局代码中的this  是指向全局对象,在浏览器中是window alert(this) //window 2.作为单纯的函数调用: function fooCoder(x) { this.x = ...

  8. 树莓派读取DHT11传感器的源代码

    import wiringpi2 as gpio owpin=8 #第8脚为1-wire脚 def getval(owpin): tl=[] #存放每个数据位的时间 tb=[] #存放数据位 gpio ...

  9. 上星期IOS的一个面试题。

    美丽说面试题 1,IOS是怎样进行内存管理的,什么是ARC. 2,声明Property时,assign,nonatomic,readonly,retain,copy(各什么意思,括号里没打印出来,我猜 ...

  10. 投资新兴市场和细分市场 good

    新兴市场对程序员来说,就是一种新的语言.一个新的平台.一套新的框架.新兴市场因为刚刚兴起,所以几乎所有人都在同一个起跑线,特别适合后进者.我认识从一个2011年开始学习iOS开发的同学,他能能力中等, ...