您的位置:首页 > 编程语言 > C#

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

2011-12-16 20:02 330 查看
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);

}

}

}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: