unity端
using System;
using System.IO;
using System.IO.MemoryMappedFiles;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
namespace ShareMemLib
{
public class ShareMemory
{
private Semaphore m_Write; //可写的信号
private Semaphore m_Read; //可读的信号
private IntPtr handle; //文件句柄
private IntPtr addr; //共享内存地址
//uint mapLength = 400000; //共享内存长
uint mapLength = 4940860; //共享内存长
//构造函参
string _writeMap = "WriteMap";
string _readMap = "ReadMap";
string _shareMemory = "shareMemory";
string _rwsMap = "ReadMapWriteMapshareMemory";
public delegate void RecMethod(string recMsg);
private RecMethod _recMethod;
private bool _isListener = false;
#region 构造函数
private ShareMemory() { }
public ShareMemory(string map, bool isListener, RecMethod RecMethod = null)
{
if (string.IsNullOrEmpty(map))
{
throw new ArgumentNullException("The map can not empty");
}
//mapLength = 1024;
_writeMap = map + "write";
_readMap = map + "read";
_shareMemory = map + "memory";
_rwsMap = _readMap + _writeMap + _shareMemory;
_recMethod = RecMethod;
if (isListener)
{
StartListening();
_isListener = true;
}
}
~ShareMemory()
{
Dispose();
}
#endregion
/// <summary>
/// 发送消息
/// </summary>
/// <param name="msg"></param>
public void Send(string msg)
{
//监听者不能发送消息,会导致监听者收到自身发送的消息
if (_isListener)
{
return;
}
try
{
m_Write = Semaphore.OpenExisting(_writeMap);
m_Read = Semaphore.OpenExisting(_readMap);
handle = OpenFileMapping(FILE_MAP_WRITE, 0, _shareMemory);
addr = MapViewOfFile(handle, FILE_MAP_ALL_ACCESS, 0, 0, 0);
Write(msg);//写入信息
m_Write.WaitOne();
m_Read.Release();
}
catch (Exception ex)
{
}
}
Thread listenTh;
/// <summary>
/// 启动监听
/// </summary>
private void StartListening()
{
m_Write = new Semaphore(1, 1, _writeMap);//开始的时候有一个可以写
m_Read = new Semaphore(0, 1, _readMap);//没有数据可读
//mapLength = 1024;
IntPtr hFile = new IntPtr(INVALID_HANDLE_VALUE);
handle = CreateFileMapping(hFile, 0, PAGE_READWRITE, 0, mapLength, _shareMemory);
addr = MapViewOfFile(handle, FILE_MAP_ALL_ACCESS, 0, 0, 0);
//启动监听线程
listenTh = new Thread(() =>
{
while (true)
{
try
{
m_Read.WaitOne();
m_Write.Release();
string recMsg = Read();
//触发接收消息处理方法
if (_recMethod != null)
{
//读取并传递接收信息
_recMethod(recMsg);
}
}
catch (Exception ex)
{
continue;
}
}
});
listenTh.Start();
}
/// <summary>
/// 读取信息
/// </summary>
/// <param name="mapName"></param>
/// <param name="encoding"></param>
private string Read(Encoding encoding = null)
{
long capacity = 1 << 10 << 10;
string output = "";
//打开共享内存
using (var mmf = MemoryMappedFile.OpenExisting(_rwsMap))
{
//使用CreateViewStream方法返回stream实例
using (var mmViewStream = mmf.CreateViewStream(0, capacity))
{
//这里要制定Unicode编码否则会出问题
using (BinaryReader rdr = new BinaryReader(mmViewStream, encoding == null ? Encoding.Unicode : encoding))
{
mmViewStream.Seek(0, SeekOrigin.Begin);
int length = rdr.ReadInt32();
char[] chars = rdr.ReadChars(length);
output = new string(chars);
}
}
}
return output;
}
MemoryMappedFile mmf;
MemoryMappedViewAccessor viewAccessor;
/// <summary>
/// 写入信息
/// </summary>
/// <param name="input"></param>
private void Write(string input)
{
long capacity = 1 << 10 << 10;
//创建或者打开共享内存
mmf = MemoryMappedFile.CreateOrOpen(_rwsMap, capacity, MemoryMappedFileAccess.ReadWrite);
//通过MemoryMappedFile的CreateViewAccssor方法获得共享内存的访问器
viewAccessor = mmf.CreateViewAccessor(0, capacity);
//向共享内存开始位置写入字符串的长度
viewAccessor.Write(0, input.Length);
//向共享内存4位置写入字符
viewAccessor.WriteArray<char>(4, input.ToArray(), 0, input.Length);
}
/// <summary>
/// 释放内存
/// </summary>
public void Dispose()
{
if (viewAccessor != null)
{
viewAccessor.Dispose();
}
if (mmf != null)
{
mmf.Dispose();
}
if (listenTh != null)
{
listenTh.Abort();
}
}
#region API
const int INVALID_HANDLE_VALUE = -1;
const int PAGE_READWRITE = 0x04;
//共享内存
[DllImport("Kernel32.dll", EntryPoint = "CreateFileMapping")]
private static extern IntPtr CreateFileMapping(IntPtr hFile, //HANDLE hFile,
UInt32 lpAttributes,//LPSECURITY_ATTRIBUTES lpAttributes, //0
UInt32 flProtect,//DWORD flProtect
UInt32 dwMaximumSizeHigh,//DWORD dwMaximumSizeHigh,
UInt32 dwMaximumSizeLow,//DWORD dwMaximumSizeLow,
string lpName//LPCTSTR lpName
);
[DllImport("Kernel32.dll", EntryPoint = "OpenFileMapping")]
private static extern IntPtr OpenFileMapping(
UInt32 dwDesiredAccess,//DWORD dwDesiredAccess,
int bInheritHandle,//BOOL bInheritHandle,
string lpName//LPCTSTR lpName
);
const int FILE_MAP_ALL_ACCESS = 0x0002;
const int FILE_MAP_WRITE = 0x0002;
[DllImport("Kernel32.dll", EntryPoint = "MapViewOfFile")]
private static extern IntPtr MapViewOfFile(
IntPtr hFileMappingObject,//HANDLE hFileMappingObject,
UInt32 dwDesiredAccess,//DWORD dwDesiredAccess
UInt32 dwFileOffsetHight,//DWORD dwFileOffsetHigh,
UInt32 dwFileOffsetLow,//DWORD dwFileOffsetLow,
UInt32 dwNumberOfBytesToMap//SIZE_T dwNumberOfBytesToMap
);
[DllImport("Kernel32.dll", EntryPoint = "UnmapViewOfFile")]
private static extern int UnmapViewOfFile(IntPtr lpBaseAddress);
[DllImport("Kernel32.dll", EntryPoint = "CloseHandle")]
private static extern int CloseHandle(IntPtr hObject);
#endregion
}
}
这里开辟了多个共享内存,实际情况看需要。
另一端
using System;
using System.IO;
using System.IO.MemoryMappedFiles;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
namespace ShareMemLib
{
public class ShareMemory
{
private Semaphore m_Write; //可写的信号
private Semaphore m_Read; //可读的信号
private IntPtr handle; //文件句柄
private IntPtr addr; //共享内存地址
uint mapLength = 4940860; //共享内存长
//构造函参
string _writeMap = "WriteMap";
string _readMap = "ReadMap";
string _shareMemory = "shareMemory";
string _rwsMap = "ReadMapWriteMapshareMemory";
public delegate void RecMethod(string recMsg);
private RecMethod _recMethod;
private bool _isListener = false;
private int ptrTemp = -1;
#region 构造函数
private ShareMemory() { }
public ShareMemory(string map, bool isListener, RecMethod RecMethod = null, int ptr = 0)
{
if (string.IsNullOrEmpty(map))
{
throw new ArgumentNullException("The map can not empty");
}
if (handle != null)
{
ptrTemp = ptr;
}
//mapLength = 1920 * 1080;
_writeMap = map + "write";
_readMap = map + "read";
_shareMemory = map + "memory";
_rwsMap = _readMap + _writeMap + _shareMemory;
_recMethod = RecMethod;
if (isListener)
{
StartListening();
_isListener = true;
}
}
~ShareMemory()
{
Dispose();
}
#endregion
/// <summary>
/// 发送消息
/// </summary>
/// <param name="msg"></param>
public void Send(string msg)
{
//监听者不能发送消息,会导致监听者收到自身发送的消息
if (_isListener)
{
return;
}
try
{
m_Write = Semaphore.OpenExisting(_writeMap);
m_Read = Semaphore.OpenExisting(_readMap);
handle = OpenFileMapping(FILE_MAP_WRITE, 0, _shareMemory);
addr = MapViewOfFile(handle, FILE_MAP_ALL_ACCESS, 0, 0, 0);
Write(msg);//写入信息
m_Write.WaitOne();
m_Read.Release();
}
catch (Exception ex)
{
}
}
Thread listenTh;
/// <summary>
/// 启动监听
/// </summary>
private void StartListening()
{
m_Write = new Semaphore(1, 1, _writeMap);//开始的时候有一个可以写
m_Read = new Semaphore(0, 1, _readMap);//没有数据可读
//mapLength = 1920 * 1080;
//IntPtr hFile = new IntPtr(INVALID_HANDLE_VALUE);
IntPtr hFile = new IntPtr(ptrTemp);
handle = CreateFileMapping(hFile, 0, PAGE_READWRITE, 0, mapLength, _shareMemory);
addr = MapViewOfFile(handle, FILE_MAP_ALL_ACCESS, 0, 0, 0);
//启动监听线程
listenTh = new Thread(() =>
{
while (true)
{
try
{
m_Read.WaitOne();
m_Write.Release();
string recMsg = Read();
//触发接收消息处理方法
if (_recMethod != null)
{
//读取并传递接收信息
_recMethod(recMsg);
}
}
catch (Exception ex)
{
continue;
}
}
});
listenTh.Start();
}
/// <summary>
/// 读取信息
/// </summary>
/// <param name="mapName"></param>
/// <param name="encoding"></param>
private string Read(Encoding encoding = null)
{
long capacity = 1 << 10 << 10;
string output = "";
//打开共享内存
using (var mmf = MemoryMappedFile.OpenExisting(_rwsMap))
{
//使用CreateViewStream方法返回stream实例
using (var mmViewStream = mmf.CreateViewStream(0, capacity))
{
//这里要制定Unicode编码否则会出问题
using (BinaryReader rdr = new BinaryReader(mmViewStream, encoding == null ? Encoding.Unicode : encoding))
{
mmViewStream.Seek(0, SeekOrigin.Begin);
int length = rdr.ReadInt32();
char[] chars = rdr.ReadChars(length);
output = new string(chars);
}
}
}
return output;
}
MemoryMappedFile mmf;
MemoryMappedViewAccessor viewAccessor;
/// <summary>
/// 写入信息
/// </summary>
/// <param name="input"></param>
private void Write(string input)
{
long capacity = 1 << 10 << 10;
//创建或者打开共享内存
mmf = MemoryMappedFile.CreateOrOpen(_rwsMap, capacity, MemoryMappedFileAccess.ReadWrite);
//通过MemoryMappedFile的CreateViewAccssor方法获得共享内存的访问器
viewAccessor = mmf.CreateViewAccessor(0, capacity);
//向共享内存开始位置写入字符串的长度
viewAccessor.Write(0, input.Length);
//向共享内存4位置写入字符
viewAccessor.WriteArray<char>(4, input.ToArray(), 0, input.Length);
}
/// <summary>
/// 释放内存
/// </summary>
public void Dispose()
{
if (viewAccessor != null)
{
viewAccessor.Dispose();
}
if (mmf != null)
{
mmf.Dispose();
}
if (listenTh != null)
{
listenTh.Abort();
}
}
#region API
const int INVALID_HANDLE_VALUE = -1;
const int PAGE_READWRITE = 0x04;
//共享内存
[DllImport("Kernel32.dll", EntryPoint = "CreateFileMapping")]
private static extern IntPtr CreateFileMapping(IntPtr hFile, //HANDLE hFile,
UInt32 lpAttributes,//LPSECURITY_ATTRIBUTES lpAttributes, //0
UInt32 flProtect,//DWORD flProtect
UInt32 dwMaximumSizeHigh,//DWORD dwMaximumSizeHigh,
UInt32 dwMaximumSizeLow,//DWORD dwMaximumSizeLow,
string lpName//LPCTSTR lpName
);
[DllImport("Kernel32.dll", EntryPoint = "OpenFileMapping")]
private static extern IntPtr OpenFileMapping(
UInt32 dwDesiredAccess,//DWORD dwDesiredAccess,
int bInheritHandle,//BOOL bInheritHandle,
string lpName//LPCTSTR lpName
);
const int FILE_MAP_ALL_ACCESS = 0x0002;
const int FILE_MAP_WRITE = 0x0002;
[DllImport("Kernel32.dll", EntryPoint = "MapViewOfFile")]
private static extern IntPtr MapViewOfFile(
IntPtr hFileMappingObject,//HANDLE hFileMappingObject,
UInt32 dwDesiredAccess,//DWORD dwDesiredAccess
UInt32 dwFileOffsetHight,//DWORD dwFileOffsetHigh,
UInt32 dwFileOffsetLow,//DWORD dwFileOffsetLow,
UInt32 dwNumberOfBytesToMap//SIZE_T dwNumberOfBytesToMap
);
[DllImport("Kernel32.dll", EntryPoint = "UnmapViewOfFile")]
private static extern int UnmapViewOfFile(IntPtr lpBaseAddress);
[DllImport("Kernel32.dll", EntryPoint = "CloseHandle")]
private static extern int CloseHandle(IntPtr hObject);
#endregion
}
}
实际是一模一样的
网友评论