Shared Memory
摘要
因工作需求用上了「Shared Memory」這個方法,因此特別整理一篇文章備忘,包含了Shard Memory運作原理,各語言的實作範例(C#, C++, Boost C++),以及如何在UE4中應用。
何謂Shared Memory (截錄自黑暗執行緒)
跨 Process溝通有個術語,Interprocess Communictaion(IPC),在 Windows 平台有以下選擇:參考
Shared Memory是C/C++開發者常用的資料交換方式,故C/C++開發者在Windows平台也常選擇它做為溝通管道。
AccessChk工具 (下載)
可透過AccessChk工具來檢視Windows目前已開啟的MemoryMappedFile。SystemInternals有個AccessChk工具能列出Windows 所有可存取的檔案、資料夾、Registry、物件以及Windows服務。而MemoryMappedFile屬於一種Windows物件。
在其中尋找MemoryMappedFile名稱,若存在可看到類似以下記錄:
\Sessions\1\BaseNamedObjects\[MemoryMappedFileName]
Type: Section
Medium Mandatory Level (Default) [No-Write-Up]
RW NT AUTHORITY\SYSTEM
SECTION_ALL_ACCESS
RW DOMAIN\UserName
SECTION_ALL_ACCESS
RW DOMAIN\UserName-S-1-5-5-0-954410
SECTION_ALL_ACCESS
各語言的Shared Memory實作範例
如何在UE4中應用Shared Memory
雖然UE4 API有提供Shared Memory方法(MapNamedSharedMemoryRegion),不過在UE4論壇裡有失敗的例子(Creating shared memory on Windows always fails),我自己嘗試在UE4.18中使用UE4 API也是仍無法正常運作。
最後是參考jgcoded作法,使用Native C++在UE4中實作Windows shared memory來解決。在本文的範例中,分為一支只寫入數值的程式 (C#, using System.IO.MemoryMappedFiles),負責建立MemoryMappedFile,寫入9個double數值,以及一支只接收數值的程式 (UE4, Native C++, include <windows.h>),負責開啟MemoryMappedFile,讀取9個double數值。
Implement shared memory from C# to UE4 (C#)
Implement shared memory from C# to UE4 (UE4)
因工作需求用上了「Shared Memory」這個方法,因此特別整理一篇文章備忘,包含了Shard Memory運作原理,各語言的實作範例(C#, C++, Boost C++),以及如何在UE4中應用。
何謂Shared Memory (截錄自黑暗執行緒)
跨 Process溝通有個術語,Interprocess Communictaion(IPC),在 Windows 平台有以下選擇:參考
- Clipboard
程式 A 將内容貼進剪貼簿,程式 B 自剪貼簿取出内容。 - COM
OLE複合文件(Compound Document)讓Word文件可以內嵌Excel工作表,點兩下還能叫出 Excel進行編輯, OLE的基礎為 COM元件技術。 - Data Copy
程序 A向程式 B依約定的格式内容傳送WM_COPYDATA訊息 - DDE
DDE是一種允許不同應用程式交換不同格式資料的通訊協定,可視為剪貼簿的沿伸,除了一次性抛轉,還能持續傳輸資料。(效能相對差,已不建議使用) - File Mapping
File Mapping意指將檔案模擬成 Process中的一塊記憶體,當多個應用程式間透過共用 File Mapping交換資料,稱之為Named Shared Memory,在各種IPC方法中效能最佳,但必須透過Mutex等同步機制防止讀寫衝突。 - Mailslots
單向溝通,Mailslot Client送訊息給Mailslot Server,訊息在Server讀取後删除,支援跨機器傳送,還可一對多廣播。(廣播訊息長度限制 400bytes,一對一傳輸時訊息長度則由 Mailslot Server建立時決定) - Pipes
雙向傳輸,分為Anonymous Pipe及Named Pipe。Anonymous Pipe一般用於父程序與子程序間的標準輸入/輸出導向,雙向溝通要建兩條Pipe,不能跨網路且限於有從屬關係的 Process;Named Pipe則可用於任意Process間交換資料,並支援跨網路Process間傳輸。 - RPC
Remote Procedure Call(RPC)允許應用程式呼叫其他應用程式提供的函式功能,並可跨網路呼叫。Windows RPC符合 ISO DCE標準,支援跨作業系統系統整合。 - Windows Sockets
基於 TCP/IP 或其他網路協定制訂的抽象通訊介面,底層透過網路連線進行資料交換。
Shared Memory是C/C++開發者常用的資料交換方式,故C/C++開發者在Windows平台也常選擇它做為溝通管道。
AccessChk工具 (下載)
可透過AccessChk工具來檢視Windows目前已開啟的MemoryMappedFile。SystemInternals有個AccessChk工具能列出Windows 所有可存取的檔案、資料夾、Registry、物件以及Windows服務。而MemoryMappedFile屬於一種Windows物件。
- 下載AccessChk工具
- 於同一目錄建立批次檔accesschk_createObjList.bat,此指令能夠列出所有物件並存檔
- 以系統管理員身份執行accesschk_createObjList.bat
在其中尋找MemoryMappedFile名稱,若存在可看到類似以下記錄:
\Sessions\1\BaseNamedObjects\[MemoryMappedFileName]
Type: Section
Medium Mandatory Level (Default) [No-Write-Up]
RW NT AUTHORITY\SYSTEM
SECTION_ALL_ACCESS
RW DOMAIN\UserName
SECTION_ALL_ACCESS
RW DOMAIN\UserName-S-1-5-5-0-954410
SECTION_ALL_ACCESS
各語言的Shared Memory實作範例
如何在UE4中應用Shared Memory
雖然UE4 API有提供Shared Memory方法(MapNamedSharedMemoryRegion),不過在UE4論壇裡有失敗的例子(Creating shared memory on Windows always fails),我自己嘗試在UE4.18中使用UE4 API也是仍無法正常運作。
最後是參考jgcoded作法,使用Native C++在UE4中實作Windows shared memory來解決。在本文的範例中,分為一支只寫入數值的程式 (C#, using System.IO.MemoryMappedFiles),負責建立MemoryMappedFile,寫入9個double數值,以及一支只接收數值的程式 (UE4, Native C++, include <windows.h>),負責開啟MemoryMappedFile,讀取9個double數值。
Implement shared memory from C# to UE4 (C#)
Implement shared memory from C# to UE4 (UE4)