Memory map streaming data in C++

0

I am collecting data from LiDAR in real time. I created a for loop to iterate over initiating a frame, collecting the data and saving it into an array (distArray). However, I am stuck with the memory mapping part. My array takes 500 integers ==> 2000 bytes of memory .. When I try to map each array element to memory using CopyMemory(), I am getting the following error "Exception thrown at 0x5843335E (vcruntime140d.dll) in file.exe: 0xC0000005: Access violation writing location 0x007E0000." .. Any ideas on how to solve this problem?

In the code below, there are a lot of functions and header calls that are irrelevant to the question, so please don't mind them ..

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <bta.h>
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <tchar.h>

#define BUF_SIZE 2000
TCHAR szName[] = TEXT("mapObjFile");

void setTOFParameters(BTA_Handle btaHandle, uint32_t newTint, uint32_t newFPS, uint32_t newFMOD);
static void errorHandling(BTA_Status status);

const int arraySize = 500;
const int numFrames = 500;
int distArray[arraySize];

int main() {

    BTA_Status status;
    BTA_Config config;
    printf("BTAinitConfig()\n\n");
    status = BTAinitConfig(&config);
    errorHandling(status);

    uint8_t udpDataIpAddr[] = { 224, 0, 0, 1 };
    config.udpDataIpAddr = udpDataIpAddr;
    config.udpDataIpAddrLen = 4;
    config.udpDataPort = 10002;
    uint8_t tcpDeviceIpAddr[] = { 192, 168, 0, 10 };
    config.tcpDeviceIpAddr = tcpDeviceIpAddr;
    config.tcpDeviceIpAddrLen = 4;
    config.tcpControlPort = 10001;

    config.frameQueueMode = BTA_QueueModeDropOldest;
    config.frameQueueLength = 500;
    config.frameMode = BTA_FrameModeDistAmp;

    // OPEN Connection
    BTA_Handle btaHandle;
    printf("BTAopen()\n\n");
    status = BTAopen(&config, &btaHandle);
    errorHandling(status);

    printf("Service running: %d\n", BTAisRunning(btaHandle));
    printf("Connection up: %d\n\n", BTAisConnected(btaHandle));

    BTA_DeviceInfo *deviceInfo;
    printf("BTAgetDeviceInfo()\n");
    status = BTAgetDeviceInfo(btaHandle, &deviceInfo);
    errorHandling(status);
    printf("Device type: 0x%x\n", deviceInfo->deviceType);
    printf("BTAfreeDeviceInfo()\n\n");
    BTAfreeDeviceInfo(deviceInfo);

    // READ Register
    uint32_t regAddr = 0x1004; //MLX75123, Register 0x1000 = I2C_ADDRESS
    uint32_t regValue;
    status = BTAreadRegister(btaHandle, regAddr, &regValue, 0);
    errorHandling(status);
    printf("BTAreadRegister : Register 0x%04X has value 0x%04X\n\n", regAddr, regValue);

    for (int i = 1; i < numFrames; i++) {
    // GET The Frame
        printf("Getting distance and amplitude data :\n");
        BTA_Frame *frame;
        printf("BTAgetFrame()\n");
        status = BTAgetFrame(btaHandle, &frame, 300);
        errorHandling(status);

        BTA_DataFormat dataFormat;
        BTA_Unit unit;
        uint16_t xRes, yRes;

        // Getting the distance data into a buffer and calculating the average amplitude over the entire frame :
        uint16_t *distances;
        printf("BTAgetDistances()\n");
        status = BTAgetDistances(frame, (void**)&distances, &dataFormat, &unit, &xRes, &yRes);
        errorHandling(status);
        if (dataFormat == BTA_DataFormatUInt16) {
            uint32_t distAvg = 0;
            for (int y = 0; y < yRes; y++) {
                for (int x = 0; x < xRes; x++) {
                    distAvg += distances[x + y * xRes];
                }
            }

            if (xRes != 0 && yRes != 0) {
                distArray[i] = distAvg / xRes / yRes;
                printf("The average distance is %d.\n", distArray[i]);  
            }
        }

    // FREE The Frame
        printf("BTAfreeFrame()\n\n");
        status = BTAfreeFrame(&frame);
        errorHandling(status);

    // ----------------------- Memory Mapping -----------------------
        HANDLE hMapFile;
        LPCTSTR pBuf;

        hMapFile = CreateFileMapping(
            INVALID_HANDLE_VALUE,    // use paging file
            NULL,                    // default security
            PAGE_READWRITE,          // read/write access
            0,                       // maximum object size (high-order DWORD)
            BUF_SIZE,                // maximum object size (low-order DWORD)
            szName);                 // name of mapping object
        if (hMapFile == NULL)
        {
            _tprintf(TEXT("Could not create file mapping object (%d).\n"),
                GetLastError());
            return 1;
        }
        pBuf = (LPTSTR)MapViewOfFile(hMapFile,            // handle to map object
                                     FILE_MAP_READ, // read/write permission
                                     0,
                                     0,
                                     BUF_SIZE);
        if (pBuf == NULL)
        {
            _tprintf(TEXT("Could not map view of file (%d).\n"),
                GetLastError());

            CloseHandle(hMapFile);

            return 1;
        }

        CopyMemory((PVOID)pBuf, &distArray, BUF_SIZE);
        _getch();

        /*UnmapViewOfFile(pBuf);

        CloseHandle(hMapFile);*/

    }

    // CLOSE Connection
    printf("BTAclose()\n\n");
    status = BTAclose(&btaHandle);
    errorHandling(status);


    // END Program
    printf("Hit <ENTER> to close the window .. ");
    fgetc(stdin);
}

After mapping the data to the memory, I will be using the mmap library in Python (https://docs.python.org/3.0/library/mmap.html) to access the data based on the tagname parameter ...

c++
memory-mapping
asked on Stack Overflow Nov 21, 2019 by Muhamed_Farooq • edited Nov 21, 2019 by Muhamed_Farooq

1 Answer

2

See here: https://docs.microsoft.com/en-us/previous-versions/windows/desktop/legacy/aa366535(v%3Dvs.85)

void CopyMemory(
  _In_       PVOID  Destination,
  _In_ const VOID   *Source,
  _In_       SIZE_T Length
);

first parameter is the destination, the second is source. But in your code you have:

CopyMemory((PVOID)pBuf, &distArray, BUF_SIZE);

... the other way around. So the exception is because you copy data from distArray to pBuf which is the mapping of read only memory.

answered on Stack Overflow Nov 21, 2019 by marcinj

User contributions licensed under CC BY-SA 3.0