适合 unity与winform WPF之间交互,仅支持PC,使用.net4.5.2内含有的功能,在csdn上花积分学的,直接上主要代码,经测试,unity发布exe之间也可使用,unity与winform、wpf之间也可使用,前提是unity只要支持.NET 4.x的都可以使用,并定义了发送者和监听者,根据自己需求自己改吧,直接上代码:《感谢原作者,积分购买应该可以公开吧,不清除,先公开,不合适就撤,哈哈。。。》
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; //共享内存长
//构造函参
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
}
}