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; //可寫(xiě)的信號(hào)
private Semaphore m_Read; //可讀的信號(hào)
private IntPtr handle; //文件句柄
private IntPtr addr; //共享內(nèi)存地址
//uint mapLength = 400000; //共享內(nèi)存長(zhǎng)
uint mapLength = 4940860; //共享內(nèi)存長(zhǎng)
//構(gòu)造函參
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 構(gòu)造函數(shù)
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>
/// 發(fā)送消息
/// </summary>
/// <param name="msg"></param>
public void Send(string msg)
{
//監(jiān)聽(tīng)者不能發(fā)送消息熄云,會(huì)導(dǎo)致監(jiān)聽(tīng)者收到自身發(fā)送的消息
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);//寫(xiě)入信息
m_Write.WaitOne();
m_Read.Release();
}
catch (Exception ex)
{
}
}
Thread listenTh;
/// <summary>
/// 啟動(dòng)監(jiān)聽(tīng)
/// </summary>
private void StartListening()
{
m_Write = new Semaphore(1, 1, _writeMap);//開(kāi)始的時(shí)候有一個(gè)可以寫(xiě)
m_Read = new Semaphore(0, 1, _readMap);//沒(méi)有數(shù)據(jù)可讀
//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);
//啟動(dòng)監(jiān)聽(tīng)線程
listenTh = new Thread(() =>
{
while (true)
{
try
{
m_Read.WaitOne();
m_Write.Release();
string recMsg = Read();
//觸發(fā)接收消息處理方法
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 = "";
//打開(kāi)共享內(nèi)存
using (var mmf = MemoryMappedFile.OpenExisting(_rwsMap))
{
//使用CreateViewStream方法返回stream實(shí)例
using (var mmViewStream = mmf.CreateViewStream(0, capacity))
{
//這里要制定Unicode編碼否則會(huì)出問(wèn)題
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>
/// 寫(xiě)入信息
/// </summary>
/// <param name="input"></param>
private void Write(string input)
{
long capacity = 1 << 10 << 10;
//創(chuàng)建或者打開(kāi)共享內(nèi)存
mmf = MemoryMappedFile.CreateOrOpen(_rwsMap, capacity, MemoryMappedFileAccess.ReadWrite);
//通過(guò)MemoryMappedFile的CreateViewAccssor方法獲得共享內(nèi)存的訪問(wèn)器
viewAccessor = mmf.CreateViewAccessor(0, capacity);
//向共享內(nèi)存開(kāi)始位置寫(xiě)入字符串的長(zhǎng)度
viewAccessor.Write(0, input.Length);
//向共享內(nèi)存4位置寫(xiě)入字符
viewAccessor.WriteArray<char>(4, input.ToArray(), 0, input.Length);
}
/// <summary>
/// 釋放內(nèi)存
/// </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;
//共享內(nèi)存
[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
}
}
這里開(kāi)辟了多個(gè)共享內(nèi)存,實(shí)際情況看需要挺邀。
另一端
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; //可寫(xiě)的信號(hào)
private Semaphore m_Read; //可讀的信號(hào)
private IntPtr handle; //文件句柄
private IntPtr addr; //共享內(nèi)存地址
uint mapLength = 4940860; //共享內(nèi)存長(zhǎng)
//構(gòu)造函參
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 構(gòu)造函數(shù)
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>
/// 發(fā)送消息
/// </summary>
/// <param name="msg"></param>
public void Send(string msg)
{
//監(jiān)聽(tīng)者不能發(fā)送消息,會(huì)導(dǎo)致監(jiān)聽(tīng)者收到自身發(fā)送的消息
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);//寫(xiě)入信息
m_Write.WaitOne();
m_Read.Release();
}
catch (Exception ex)
{
}
}
Thread listenTh;
/// <summary>
/// 啟動(dòng)監(jiān)聽(tīng)
/// </summary>
private void StartListening()
{
m_Write = new Semaphore(1, 1, _writeMap);//開(kāi)始的時(shí)候有一個(gè)可以寫(xiě)
m_Read = new Semaphore(0, 1, _readMap);//沒(méi)有數(shù)據(jù)可讀
//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);
//啟動(dòng)監(jiān)聽(tīng)線程
listenTh = new Thread(() =>
{
while (true)
{
try
{
m_Read.WaitOne();
m_Write.Release();
string recMsg = Read();
//觸發(fā)接收消息處理方法
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 = "";
//打開(kāi)共享內(nèi)存
using (var mmf = MemoryMappedFile.OpenExisting(_rwsMap))
{
//使用CreateViewStream方法返回stream實(shí)例
using (var mmViewStream = mmf.CreateViewStream(0, capacity))
{
//這里要制定Unicode編碼否則會(huì)出問(wèn)題
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>
/// 寫(xiě)入信息
/// </summary>
/// <param name="input"></param>
private void Write(string input)
{
long capacity = 1 << 10 << 10;
//創(chuàng)建或者打開(kāi)共享內(nèi)存
mmf = MemoryMappedFile.CreateOrOpen(_rwsMap, capacity, MemoryMappedFileAccess.ReadWrite);
//通過(guò)MemoryMappedFile的CreateViewAccssor方法獲得共享內(nèi)存的訪問(wèn)器
viewAccessor = mmf.CreateViewAccessor(0, capacity);
//向共享內(nèi)存開(kāi)始位置寫(xiě)入字符串的長(zhǎng)度
viewAccessor.Write(0, input.Length);
//向共享內(nèi)存4位置寫(xiě)入字符
viewAccessor.WriteArray<char>(4, input.ToArray(), 0, input.Length);
}
/// <summary>
/// 釋放內(nèi)存
/// </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;
//共享內(nèi)存
[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
}
}
實(shí)際是一模一樣的