The producer process must be started first. It created the shared memory area based upon a name, and two events. It also writes an initial string to the shared memory, then sets a read event, then waits on a send event trigger. The consumer process reads in the memory, sets a write event, then waits on a read event trigger.
Code: Select all
; shm_producer.pb
EnableExplicit
Define version.s = "1.0.01e"
Define hMap.i
Define result.i
Define mapName.s = "SharedMapName"
Define readEventNumber.i
Define sendEventNumber.i
Define sendStr.s = ""
Define mapSize.i = 16384
Define stringLen.i
readEventNumber = CreateEvent_(0, 0, 0, "read_" + mapName + "_event")
sendEventNumber = CreateEvent_(0, 0, 0, "send_" + mapName + "_event")
; procedure to write data to the shared memory map
Procedure.i WriteMapString(*mapName, *sendMemory, stringLen)
Protected hFileMap.i
Protected *mapView
Protected retValue.i = #False
hFileMap = OpenFileMapping_(#FILE_MAP_WRITE, 0, *mapName)
If hFileMap
*mapView = MapViewOfFile_(hFileMap, #FILE_MAP_WRITE, 0, 0, 0)
If *mapView
CopyMemory(*sendMemory, *mapView, stringLen)
PokeA(*mapView + stringLen, 0)
retValue = #True
UnmapViewOfFile_(*mapView)
Else
retValue = -2
EndIf
CloseHandle_(hFileMap)
Else
retValue = -1
EndIf
ProcedureReturn retValue
EndProcedure
; use the #INVALID_HANDLE_VALUE to tell the system to use memory, not a physical file!
hMap = CreateFileMapping_(#INVALID_HANDLE_VALUE, #Null, #PAGE_READWRITE, 0, mapSize + 1, @mapName)
OpenConsole("Shared Map Producer, version: " + version)
sendStr = "Started Shared Map Producer"
stringLen = Len(sendStr)
result = WriteMapString(@mapName, @sendStr, stringLen)
If result > 0
PrintN("Send to shared Map, initial value sent is: " + sendStr + ", packet sent ok")
Else
PrintN("Error writing data to shared map, process will terminate, result = " + Str(result))
Input()
End
EndIf
Repeat
Print("Enter text To send, or press <enter> to quit: ")
sendStr = Input()
stringLen = Len(sendStr)
If stringLen > 0
If stringLen > mapSize
stringLen = mapSize
sendStr = LSet(sendStr, stringLen)
EndIf
result = WriteMapString(@mapName, @sendStr, stringLen)
SetEvent_(readEventNumber)
WaitForSingleObject_(sendEventNumber, #INFINITE)
Else
SetEvent_(readEventNumber)
Break
EndIf
ForEver
CloseHandle_(hMap)
CloseConsole()
End
; IDE Options = PureBasic 5.42 LTS (Windows - x64)
; CursorPosition = 17
; FirstLine = 3
; Executable = shm_producer.exe
; DisableDebugger
; HideErrorLog
; CompileSourceDirectory
; EnableCompileCount = 9
; EnableBuildCount = 9
; EnableExeConstant
Code: Select all
; shm_consumer.pb
EnableExplicit
Define version.s = "1.0.01e"
Define lenSent.i
Define sentText.s
Define mapName.s = "SharedMapName"
Define readEventNumber.i
Define sendEventNumber.i
Define eventNumber.i
Define firstTime.i = #True
Define *recvString = AllocateMemory(16384)
readEventNumber = CreateEvent_(0, 0, 0, "read_" + mapName + "_event")
sendEventNumber = CreateEvent_(0, 0, 0, "send_" + mapName + "_event")
; procedure to open he shared memory map, and read the data
Procedure.i GetMapPointer(*mapName, *recvMemory)
Protected lenSent.i = 0
Protected *mapView
Protected hFileMap.i
Protected sentText.s
hFileMap = OpenFileMapping_(#FILE_MAP_READ, 0, *mapName)
If hFileMap
*mapView = MapViewOfFile_(hFileMap, #FILE_MAP_READ, 0, 0, 0)
If *mapView
sentText = PeekS(*mapView)
lenSent = Len(sentText)
UnmapViewOfFile_(*mapView)
EndIf
CloseHandle_(hFileMap)
If lenSent
lenSent = PokeS(*recvMemory, sentText, lenSent)
EndIf
EndIf
ProcedureReturn lenSent
EndProcedure
OpenConsole("Shared Map Consumer, version: " + version)
Repeat
lenSent = GetMapPointer(@mapName, *recvString)
If lenSent > 0
sentText = PeekS(*recvString, lenSent)
PrintN("Read Map = " + Str(lenSent) + " bytes received: " + sentText)
If firstTime
firstTime = #False
EndIf
SetEvent_(sendEventNumber)
WaitForSingleObject_(readEventNumber, #INFINITE)
Else
Break
EndIf
ForEver
If firstTime
PrintN("The shared memory producer must be started first!")
Input()
EndIf
CloseConsole()
End
; IDE Options = PureBasic 5.42 LTS (Windows - x64)
; CursorPosition = 18
; FirstLine = 3
; Executable = shm_consumer.exe
; DisableDebugger
; HideErrorLog
; CompileSourceDirectory
; EnableCompileCount = 11
; EnableBuildCount = 11
; EnableExeConstant