Search code examples
visual-c++mfcregistrystdvectorbinary-data

Reading and writing a std::vector<int> to / from registry with WriteProfileBinary


I am getting myself into a pickle here!

I have a simple <std::vector<int> container and what I want to do is read / write it to a binary registry key. I started with:

    std::vector<int> vSortedColumnIndexInfo = dlgColumns.SortedEditorColumnIndexInfo();
    theApp.WriteProfileBinary(_T("Options"), _T("EditorSortedColumnIndexInfo"), 
        vSortedColumnIndexInfo.data, 
        vSortedColumnIndexInfo.size);

But this will not compile:

error C3867: std::vector<int,std::allocator<int>>::data: non-standard syntax; use & to create a pointer to member

error C3867: std::vector<int,std::allocator<int>>::size: non-standard syntax; use & to create a pointer to member

Why is it saying this? What is the correct way to read / write a std::vector<int> to / from a binary registry key? It can be changed from an int if required.


Update 1

Based on the comments I now have:

std::vector<int> vSortedColumnIndexInfo = dlgColumns.SortedEditorColumnIndexInfo();
theApp.WriteProfileBinary(_T("Options"), _T("EditorSortedColumnIndexInfo"), 
    reinterpret_cast<BYTE*>(vSortedColumnIndexInfo.data()),
    gsl::narrow<UINT>(vSortedColumnIndexInfo.size() * sizeof(int)));

Solution

  • Since I know my values will be under 256 I have decided to stick with BYTE for the container.

    Writing to Registry

    std::vector<BYTE> vExcludedColumns;
    
    // POpulate vector
    
    UINT uSize = gsl::narrow<UINT>(sizeof(BYTE) * vExcludedColumns.size());
    theApp.WriteProfileBinary(
        strSection, 
        _T("AssignStatesEx"),
        vExcludedColumns.data(),
        uSize
    );
    theApp.WriteProfileInt(strSection, _T("AssignStatesExSize"), uSize);
    

    Reading from Registry

    std::vector<BYTE> vExcludedColumns;
    UINT uSize = theApp.GetProfileInt(strSection, _T("AssignStatesExSize"), 0);
    UINT uSizeRead = 0;
    BYTE* temp = nullptr;
    theApp.GetProfileBinary(strSection, _T("AssignStatesEx"), &temp, &uSizeRead);
    if (uSizeRead == uSize)
    {
        vExcludedColumns.resize(uSizeRead, 0);
        memcpy(vExcludedColumns.data(), temp, uSizeRead);
    }
    delete[] temp;
    temp = nullptr;
    

    I believe that this will still work for both 32 bit and 64 bit.

    I am open to comments if this code can be improved or simplified.


    Updated

    Here is the same code, but added into public app methods:

    std::vector<BYTE> CMeetingScheduleAssistantApp::GetProfileVector(CString strSection, CString strKey)
    {
        std::vector<BYTE> vData;
        UINT uSize = theApp.GetProfileInt(strSection, strKey + _T("Size"), 0);
        UINT uSizeRead = 0;
        BYTE* temp = nullptr;
        theApp.GetProfileBinary(strSection, strKey, &temp, &uSizeRead);
        if (uSizeRead == uSize)
        {
            vData.resize(uSizeRead, 0);
            memcpy(vData.data(), temp, uSizeRead);
        }
        delete[] temp;
        temp = nullptr;
        return vData;
    }
    
    
    void CMeetingScheduleAssistantApp::WriteProfileVector(CString strSection, CString strKey, std::vector<BYTE> vData)
    {
        UINT uSize = gsl::narrow<UINT>(sizeof(BYTE) * vData.size());
        theApp.WriteProfileBinary(
            strSection,
            strKey,
            vData.data(),
            uSize
        );
        theApp.WriteProfileInt(strSection, strKey + _T("Size"), uSize);
    }