C# 共享内存(转)
以下是一个C#操作内存的一个类,只要将下面的类添加到相应的项目中,该项目就可以对内存进行直接操作!
using System.Runtime.InteropServices; //添加如下命名空间 需要是用 DllImport
public class ShareMemLib
{
[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 ShareMemLib()
{
}
~ShareMemLib()
{
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 (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;
}
//关闭共享内存
public void Close()
{
if (m_bInit)
{
UnmapViewOfFile(m_pwData);
CloseHandle(m_hSharedMemoryFile);
}
}
///读数据
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;
}
//将数据写入共享内存中
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;
}
}
调用方法:
声明 ShareMemery.ShareMemLib MemDB = new ShareMemLib(); 为公共的变量
//用下面这句话调用上面类中的初始化共享内存的方法
if (MemDB.Init("YFMemTest", 10240) != 0)
将需要写在内存中的数据:转化成为byte[]
MemDB.Write(bytData, 0, bb.Length); //将数据写入到共享内存中
byte[] bytData = new byte[16];
int intRet = MemDB.Read(ref bytData, 0, 16);
以上方法是读出内存中的16个字节的内容
以上方法在VS2008中经过测试。
C# 共享内存(转)的更多相关文章
- Linux 共享内存详解一
共享内存段被多个进程附加的时候,如果不是所有进程都已经调用shmdt,那么删除该共享内存段时,会出现一个临时的不完整的共享内存段(key值是0),无法彻底删除.只有当所有进程都调用shmdt,这个临时 ...
- PHP进程通信基础——信号量+共享内存通信
PHP进程通信基础--信号量+共享内存通信 由于进程之间谁先执行并不确定,这取决于内核的进程调度算法,其中比较复杂.由此有可能多进程在相同的时间内同时访问共享内存,从而造成不可预料的错误.信号量这个名 ...
- C++ 共享内存 函数封装
#pragma once #include <string> #include <wtypes.h> #include <map> using namespace ...
- Linux学习笔记(14)-进程通信|共享内存
在Linux中,共享内存是允许两个不相关的进程访问同一个逻辑内存的进程间通信方法,是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式. 不同进程之间共享的内存通常安排为同一段物理内存.进程可 ...
- linux 共享内存 shmat,shmget,shmdt,shmctl
shmget int shmget(key_t key, size_t size, int flag);//开辟一段共享内存 key_t key :标识符的规则() size_t size :共享内存 ...
- Linux进程间通信(六):共享内存 shmget()、shmat()、shmdt()、shmctl()
下面将讲解进程间通信的另一种方式,使用共享内存. 一.什么是共享内存 顾名思义,共享内存就是允许两个不相关的进程访问同一个逻辑内存.共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式 ...
- linux后台查看共享内存和消息队列的命令
ipcs ipcs -q : 显示所有的消息队列 ipcs -qt : 显示消息队列的创建时间,发送和接收最后一条消息的时间 ipcs -qp: 显示往消息队列中放消息和从消息队列中取消息的进程ID ...
- c++共享内存(转载)
对于连个不同的进程之间的通信,共享内存是一种比较好的方式,一个进程把数据发送到共享内存中, 另一个进程可以读取改数据,简单记录一下代码 #define BUF_SIZE 256 TCHAR szNam ...
- OpenMP共享内存并行编程详解
实验平台:win7, VS2010 1. 介绍 平行计算机可以简单分为共享内存和分布式内存,共享内存就是多个核心共享一个内存,目前的PC就是这类(不管是只有一个多核CPU还是可以插多个CPU,它们都有 ...
- android共享内存
在android下不能通过shm_open使用共享内存. 网上有好多关于android下使用Ashmem实现共享内存的,但经过尝试该方法可以mmap出内存,但是和另一个进程没有实现共享. 具体的使用方 ...
随机推荐
- [USACO13NOV]No Change
题目大意: 你有k(k<=16)个硬币,每个硬币都有自己的面值. 现在你要给n件商品付钱,每件商品也有自己的价格. 然而老板是个奸商,他绝对不会给你找钱. 你每次付钱只能用一个硬币,但是你可以一 ...
- Problem J: 零起点学算法105——C语言合法标识符
#include<stdio.h> #include<ctype.h>//调用isalpha函数 int main() { int n; ]; while(scanf(&quo ...
- Problem A: 零起点学算法80——逆序输出(数组练习)
#include<stdio.h> int main() { ]; scanf("%d",&n); ;i<=n;i++){ scanf("%d& ...
- Wunder Fund Round 2016 (Div. 1 + Div. 2 combined) F. Double Knapsack 鸽巢原理 构造
F. Double Knapsack 题目连接: http://www.codeforces.com/contest/618/problem/F Description You are given t ...
- YS动态口令系统接入流程
动态口令是保护用户账户的一种常见有效手段,即用户进行敏感操作(比如登录)时,需要用户提供此动态生成的口令做二次身份验证,假设用户的口令被盗,如果没有动态口令,也无法进行登录或进行敏感操作,保护了用户的 ...
- json字符串生成C#实体类的工具
转载:http://www.cnblogs.com/finesite/archive/2011/07/31/2122984.html json作为互联网上轻量便捷的数据传输格式,越来越受到重视.但在服 ...
- 在Visual Studio中开发Matlab mex文件,生成mexw64/mexw32
csunking贡献,2015-9-22 1712 1. 概述 通过使用C/C++与Matlab混合编程,既可以享受到C代码快速执行的速度,又可以方便的使用Matlab众多的库函数和强大的绘图功能 ...
- ECMAScript 6(ES6)常用语法
一:Let和const (1)Let定义块级作用域的变量,var定义的变量会提升.Let不会提升. 如下.var可以先用,打印是undefined但是let在定义之前是不能用的. 会报错Uncaug ...
- 基于Python的交互式访问
应用迁移中遇到一些有特殊要求的应用,比如需要通过交互生成一些新的config文件,然后启动应用需要依赖于这些文件,这样在构建镜像的时候基本上是没有办法把这些文件固定的,因为他需要根据运行环境去进行动态 ...
- ubuntu-14.04.5 升级sshd到指定版本openssh-7.7p1,openssl-1.1.0h。
升级步骤 wget https://wps-oss.oss-cn-shenzhen.aliyuncs.com/openssh_update.tar.gz tar xvf openssh_update. ...