Eksportowanie do współdzielonej pamięci (shared memory)
Dane są eksportowane do współdzielonej pamięci. Nazwa współdzielonej pamięci
to "GPxCInfo".
Jest ona chroniona przez mutex o nazwie "GPxCInfo_Mutex".
Zawartość współdzielonej pamięci jest zdefiniowana przez następującą strukturę:
#ifdef _MSC_VER
#pragma pack(push, 1)
#else
#pragma pack(1)
#endif
#ifndef BYTE
#define BYTE unsigned char
#endif
#ifndef WORD
#define WORD unsigned short
#endif
#ifndef DWORD
#define DWORD unsigned int
#endif
#define GPXCINFO_NAME "GPxCInfo"
#define GPXCINFO_MUTEX_NAME GPXCINFO_NAME"_Mutex"
#define GPX_CIF_PITLIGHT 0x01 // set if pit light is on
struct GPxCInfoData {
BYTE flags; // see GPX_CIF_* defines above
BYTE lap; // lap number (numer okrążenia)
BYTE position; // race position (pozycja w wyścigu)
WORD fuel; // fuel laps (value = fuel laps * 10) (paliwo w okrążeniach)
BYTE temp; // water temperature (temperatura wody)
int speed; // rounded speed in either kph or mph (zaokrglona prędkość w kph lub mph)
DWORD splittime; // last split or lap time (ostatni czas sektory lub całego okrążenia)
char gear; // gear (bieg)
WORD revs; // rpm (obroty na minutę)
DWORD time; // session time in millis (czas sesji)
DWORD timeFront; // difference in millis to driver in front (or 0xc0000000 if n/a) (różnica do kierowcy przed tobą)
DWORD timeBehind; // difference in millis to driver behind (or 0xc0000000 if n/a) (różnica do kierowcy za tobą)
char driverFront[24]; // initial and last name of driver in front, if available (pierw. i ostat. człon nazwy kierowcy przed tobą)
char driverBehind[24]; // initial and last name of driver behind, if available (pierw. i ostat. człon nazwy kierowcy za tobą)
};
#ifdef _MSC_VER
#pragma pack(pop)
#else
#pragma pack()
#endif
The contents are updated each frame. Here is sample code of how to access it:
static const size_t DATA_SIZE = sizeof(GPxCInfoData);
static GPxCInfoData *pData = NULL;
static LPVOID pSharedData = NULL;
static HANDLE hFileMapping = NULL;
static HANDLE hMutex = NULL;
static BOOL WINAPI ConsoleCtrlHandler(DWORD dwCtrlType);
static bool Init();
static void End();
static bool Read();
static BOOL WINAPI ConsoleCtrlHandler(DWORD dwCtrlType)
{
End();
return FALSE;
}
static bool Init()
{
SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE);
hFileMapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, DATA_SIZE, GPXCINFO_NAME);
if (hFileMapping == NULL) {
fprintf(stderr, "Error creating file mapping: last error = %d\n", GetLastError());
return false;
}
pSharedData = MapViewOfFile(hFileMapping, FILE_MAP_WRITE, 0, 0, 0);
if (pSharedData == NULL) {
fprintf(stderr, "Error mapping view of file: last error = %d\n", GetLastError());
return false;
}
hMutex = CreateMutex(NULL, FALSE, GPXCINFO_MUTEX_NAME);
if (hMutex == NULL) {
fprintf(stderr, "Error creating mutex: last error = %d\n", GetLastError());
return false;
}
pData = new GPxCInfoData;
return true;
}
static void End()
{
fprintf(stderr, "Cleaning up...\n");
delete pData;
pData = NULL;
if (hMutex != NULL) {
CloseHandle(hMutex);
hMutex = NULL;
}
if (pSharedData != NULL) {
UnmapViewOfFile(pSharedData);
pSharedData = NULL;
}
if (hFileMapping != NULL) {
CloseHandle(hFileMapping);
hFileMapping = NULL;
}
SetConsoleCtrlHandler(ConsoleCtrlHandler, FALSE);
}
static bool Read()
{
bool ret = false;
// obtain mutex ownership
DWORD dwWaitResult = WaitForSingleObject(hMutex, 1000);
switch (dwWaitResult) {
case WAIT_OBJECT_0:
__try {
__try {
// copy data from shared memory
memcpy(pData, pSharedData, DATA_SIZE);
ret = true;
}
__except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER :
EXCEPTION_CONTINUE_SEARCH) {
fprintf(stderr, "Access violation while reading data from shared memory\n");
}
}
__finally {
// release ownership
if (!ReleaseMutex(hMutex))
fprintf(stderr, "Error releasing mutex: last error = %d\n", GetLastError());
}
break;
case WAIT_FAILED:
fprintf(stderr, "Error waiting for object: last error = %d\n", GetLastError());
break;
case WAIT_TIMEOUT:
fprintf(stderr, "Timed out waiting for lock\n");
break;
}
return ret;
}
int main(int argc, char* argv[])
{
if (Init()) {
for (;;) {
Read();
fprintf(stdout, "%d\n", pData->speed);
Sleep(500);
}
}
End();
return 0;
}