进程通信--内存共享

共享内存其实就是访问计算机系统的共享域。这是一种系统内核级资源,数据量太大就考虑别的方式吧。如果是普通windows程序调用windowsAPI或者升级.net framework版本到4.5,就有内存文件映射的函数。在 System.IO.MemoryMappedFiles这个命名空间下。

一、使用MemoryMappedFiles创建内存文件

引入System.IO.MemoryMappedFiles命名空间
用MemoryMappedFile.CreateOrOpen读写内存文件,然后使用CreateViewStream()这个函数创建一个流,通过BinaryReader或者BinaryWriter来读取或者写入文件。我用unity2017.3,然后把.net framework版本调成4.6,我发现在unity里还是找不到这个命名空间,所以想用这种方式在unity里还是不适用的。如果是通过vs写的普通windows程序,可以试试这种方式。

这里写的很详细了:https://www.cnblogs.com/zeroone/archive/2012/04/18/2454776.html

二、调用windowsAPI
其实用到了CreateFileMapping,MapViewOfFile,OpenFileMapping,UnmapViewOfFile,CloseHandle这几个函数。这个函数可以在www.pinvoke.net里找到,并且有详细的解释。很多常用的windowsAPI都能从这个网站上查看。
这几个函数直接通过C#使用,如链接里边的https://bbs.csdn.net/topics/340222864,这样在普通的windows程序种没问题,但是放到unity 里有时候只能单向通信,实现不了双向通信。
然后你把这个几个函数在c++里包装一层,然后在通过C# 调用,这样就没问题了。 由于文件牵扯很多其他的东西,我在这把关键的代码贴出,有问题私信我就可以
创建内存文件

    BYTE* __stdcall Create(LPCWSTR fName)
    {
HANDLE file = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, MAP_SIZE, fName);
        LPBYTE pView = (LPBYTE)MapViewOfFile(file , FILE_MAP_ALL_ACCESS, 0, VIEW_OFFSET, VIEW_SIZE);
        return pView;
}        

BYTE* __stdcall Open(LPCWSTR fName)
{
HANDLE  hS = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, fName);
        LPBYTE  pView = (LPBYTE)MapViewOfFile(hS, FILE_MAP_ALL_ACCESS, 0, VIEW_OFFSET, VIEW_SIZE);
        return pView;
}       

使用方法
[DllImport(“Dll名字”, EntryPoint = “Create”)]
private extern static IntPtr Create(string fname);

[DllImport(“Dll名字”, EntryPoint = “Open”)]
private extern static IntPtr Open(string fname);
这两个函数返回的是文件句柄,使用的时候直接用数组copy,把数据copy的这个句柄上就可以了

你可能感兴趣的:(Unity3d,C#)