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


    原文:http://blog.csdn.net/yfiot/article/details/1717458

            VC++的共享内存操作代码实现起来相对比较容易,但是用C#语言来实现,就有一定难度,由于工作需要,把以前VC开发的共享内存代码要用C#实现,别说,还费了不少周折,毕竟C#操作API函数和地址指针不是那么直接,还好,总算完成了,效果还不错。

         

    共享内存操作类:    

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

    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;
            bool m_bAlreadyExist = false;
            bool m_bInit = false;
            long m_MemSize=0;

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

            /// <summary>
            /// 初始化共享内存
            /// </summary>
            /// <param name="strName">共享内存名称</param>
            /// <param name="lngSize">共享内存大小</param>
            /// <returns></returns>
            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 (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_WRITE, 0, 0, (uint)lngSize);
                    if (m_pwData == IntPtr.Zero)
                    {
                        m_bInit = false;
                        CloseHandle(m_hSharedMemoryFile);
                        return 3; //创建内存映射失败
                    }
                    else
                    {
                        m_bInit = true;
                        if (m_bAlreadyExist == false)
                        {
                            //初始化
                        }
                    }
                    //----------------------------------------
                }
                else
                {
                    return 1; //参数错误     
                }

                return 0;     //创建成功
            }
            /// <summary>
            /// 关闭共享内存
            /// </summary>
            public void Close()
            {
                if (m_bInit)
                {
                    UnmapViewOfFile(m_pwData);
                    CloseHandle(m_hSharedMemoryFile);
                }
            }

            /// <summary>
            /// 读数据
            /// </summary>
            /// <param name="bytData">数据</param>
            /// <param name="lngAddr">起始地址</param>
            /// <param name="lngSize">个数</param>
            /// <returns></returns>
            public int Read(ref byte[] bytData, int lngAddr, int lngSize)
            {
                if (lngAddr + lngSize > m_MemSize) return 2; //超出数据区
                if (m_bInit)
                {               
                    Marshal.Copy(m_pwData, bytData, lngAddr, lngSize);
                }
                else
                {
                    return 1; //共享内存未初始化
                }
                return 0;     //读成功
            }

            /// <summary>
            /// 写数据
            /// </summary>
            /// <param name="bytData">数据</param>
            /// <param name="lngAddr">起始地址</param>
            /// <param name="lngSize">个数</param>
            /// <returns></returns>
            public int Write(byte[] bytData, int lngAddr, int lngSize)
            {
                if (lngAddr + lngSize > m_MemSize) return 2; //超出数据区
                if (m_bInit)
                {
                    Marshal.Copy(bytData, lngAddr, m_pwData, lngSize);
                }
                else
                {
                    return 1; //共享内存未初始化
                }
                return 0;     //写成功
            }
        }
    }

    测试例程: 

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

    namespace YFShareMem
    {
        public partial class frmShareMem : Form
        {
            ShareMem MemDB=new ShareMem();
            public frmShareMem()
            {
                InitializeComponent();
            }

            private void btnOpen_Click(object sender, EventArgs e)
            {
                if (MemDB.Init("YFMemTest", 10240) != 0)
                {
                    //初始化失败
                    MessageBox.Show("初始化失败");
                }
                else
                {
                    btnOpen.Enabled = false;
                    chkWrite.Enabled = true;
                    tmrTime.Enabled = true;
                }
            }

            private void tmrTime_Tick(object sender, EventArgs e)
            {
                byte[] bytData = new byte[16];
                int intRet = MemDB.Read(ref bytData, 0, 16);
                lstData.Items.Clear(); 
                if (intRet == 0)
                {
                    for (int i = 0; i < 16; i++)
                    {
                        lstData.Items.Add(bytData[i].ToString());
                    }

                    if (chkWrite.Checked)
                    {
                        bytData[0]++;
                        bytData[1] += 2;
                        if (bytData[0] > 200) bytData[0] = 0;
                        if (bytData[1] > 200) bytData[1] = 0;
                        MemDB.Write(bytData, 0, 16);
                    }
                }           
            }

        }
    }

       

  • 相关阅读:
    单片机GPIO口模拟串口的方法
    arduino~snprintf
    #7号板问题
    stm8s + si4463 寄存器配置
    linux之cut用法
    74HC123D 引脚介绍及应用
    无线板卡接口定义
    iio adc转换应用编写
    m72 gprs模块的应用编写
    dac7562 应用层实现dac
  • 原文地址:https://www.cnblogs.com/lizhigang/p/7373224.html
Copyright © 2020-2023  润新知