Windows共享内存 C++及C#实现
(2011-08-30 19:52:28)
标签:
杂谈 |
分类: IT |
ileMapping用于将存在于磁盘的文件放进一个进程的虚拟地址空间,并在该进程的虚拟地址空间中产生一个区域用于“存放”该文件,这个空间就叫做File
View,系统并同时产生一个File Mapping
Object(存放于物理内存中)用于维持这种映射关系,这样当多个进程需要读写那个文件的数据时,它们的File
View其实对应的都是同一个File Mapping
Object,这样做可节省内存和保持数据的同步性,并达到数据共享的目的。
当然在一个应用向文件中写入数据时,其它进程不应该去读取这个正在写入的数据。这就需要进行一些同步的操作。
下边来看一下具体的API。
CreateFileMaping 的用法:
HANDLE CreateFileMapping(
//返回File Mapping
Object的句柄
HANDLE
hFile,
//
想要产生映射的文件的句柄
LPSECURITY_ATTRIBUTES lpAttributes,
//
安全属性(只对NT和2000生效)
DWORD
flProtect,
// 保护标致
DWORD
dwMaximumSizeHigh,
//
在DWORD的高位中存放
File Mapping Object
// 的大小
DWORD
dwMaximumSizeLow,
//
在DWORD的低位中存放
File Mapping Object
//
的大小(通常这两个参数有一个为0)
LPCTSTR
lpName
// File
Mapping Object的名称。
);
1) 物理文件句柄
任何可以获得的物理文件句柄,如果你需要创建一个物理文件无关的内存映射也无妨,将它设置成为
0xFFFFFFFF(INVALID_HANDLE_VALUE)就可以了.
如果需要和物理文件关联,要确保你的物理文件创建的时候的访问模式和"保护设置"匹配,比如:
物理文件只读,内存映射需要读写就会发生错误。推荐你的物理文件使用独占方式创建。
如果使用 INVALID_HANDLE_VALUE,也需要设置需要申请的内存空间的大小,无论物理文件句柄参数是否有效, 这样
CreateFileMapping 就可以创建一个和物理文件大小无关的内存空间给你,
甚至超过实际文件大小,如果你的物理文件有效,而大小参数为0,则返回给你的是一个和物理文件大小一样的内存空间地址范围。返回给你的文件映射地址空间是可以通过复制,集成或者命名得到,初始内容为0。
2) 保护设置
就是安全设置, 不过一般设置NULL就可以了,
使用默认的安全配置. 在win2k下如果需要进行限制, 这是针对那些将内存文件映射共享给整个网络上面的应用进程使用是,
可以考虑进行限制.
3) 高位文件大小
32位地址空间, 设置为0。
4) 共享内存名称
命名可以包含 "Global" 或者 "Local" 前缀在全局或者会话名空间初级文件映射. 其他部分可以包含任何除了()以外的字符,
可以参考 Kernel Object Name Spaces.
5) 调用CreateFileMapping的时候GetLastError的对应错误
ERROR_FILE_INVALID
如果企图创建一个零长度的文件映射, 应有此报
ERROR_INVALID_HANDLE
如果发现你的命名内存空间和现有的内存映射, 互斥量, 信号量, 临界区同名就麻烦了
ERROR_ALREADY_EXISTS
表示内存空间命名已经存在
使用函数CreateFileMapping创建一个想共享的文件数据句柄,然后使用MapViewOfFile来获取共享的内存地址,然后使用OpenFileMapping函数在另一个进程里打开共享文件的名称,这样就可以实现不同的进程共享数据。
下边是C#是对使用的接口函数声明:
[DllImp ort("kernel32",
SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr CreateFile(string lpFileName,
int
dwDesiredAccess, int dwShareMode, IntPtr
lpSecurityAttributes,
int
dwCreationDisposition, int
dwFlagsAndAttributes,
当然在一个应用向文件中写入数据时,其它进程不应该去读取这个正在写入的数据。这就需要进行一些同步的操作。
下边来看一下具体的API。
1) 物理文件句柄
如果需要和物理文件关联,要确保你的物理文件创建的时候的访问模式和"保护设置"匹配,比如: 物理文件只读,内存映射需要读写就会发生错误。推荐你的物理文件使用独占方式创建。
如果使用 INVALID_HANDLE_VALUE,也需要设置需要申请的内存空间的大小,无论物理文件句柄参数是否有效, 这样 CreateFileMapping 就可以创建一个和物理文件大小无关的内存空间给你, 甚至超过实际文件大小,如果你的物理文件有效,而大小参数为0,则返回给你的是一个和物理文件大小一样的内存空间地址范围。返回给你的文件映射地址空间是可以通过复制,集成或者命名得到,初始内容为0。
2) 保护设置
3) 高位文件大小
32位地址空间, 设置为0。
4) 共享内存名称
命名可以包含 "Global" 或者 "Local" 前缀在全局或者会话名空间初级文件映射. 其他部分可以包含任何除了()以外的字符, 可以参考 Kernel Object Name Spaces.
5) 调用CreateFileMapping的时候GetLastError的对应错误
使用函数CreateFileMapping创建一个想共享的文件数据句柄,然后使用MapViewOfFile来获取共享的内存地址,然后使用OpenFileMapping函数在另一个进程里打开共享文件的名称,这样就可以实现不同的进程共享数据。
下边是C#是对使用的接口函数声明:
[DllImp
public static extern IntPtr CreateFile(string lpFileName,