文章1:http://www.bianceng.cn/Programming/csharp/201107/27601_2.htm
相关的代码:
源码(工程文件)下载地址:
http://download.csdn.net/source/798731
本工程在以下环境下编译通过:
Windows XP SP3
Microsoft VisualC# 2005
Microsoft VisualStudio 2005 V8.0.50727.42
Microsoft .NET Framework V2.0.50727
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////:
文章2: 百度的一篇文章 http://wenku.baidu.com/view/ebee66d0b9f3f90f76c61bf6.html
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
文章3:原文:http://blog.csdn.net/yefanqiu/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);
////一篇关于CreateFileMapping使用方法的blog http://blog.csdn.net/khuang2008/article/details/3949720
[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);
%也可以用一下的方法写:
m_pwDataWrite = (IntPtr)(m_pwData.GetHashCode()+ m_length );// + m_length通过改指针的位置可以控制写入点
Marshal.Copy(bytData, 0, m_pwDataWrite, 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
);
}
}
}
}
}