1

I have a std::vector which will be filled with instructions for some proprietary hardware. I have code to construct this buffer and manipulate it just fine.

The problem is I need to make use of another library (C based) which builds similar proprietary hardware instructions, but the library expects us to make raw memory available and return a pointer to it, which the library then uses to write its commands.

I would like to accomplish something like the following [pseudo code, nothing like the real code]:

    void* theLibraryCallback (void* clientData, unsigned int theLibrarySize)
    {
        std::vector<unsigned int> cmd = reinterpret_cast<std::vector<unsigned int>>(clientData);
        std::vector<unsigned int>::size_type cmdSize = cmd->size();

        for (int loop=0;loop<theLibrarySize; loop++)
            cmd->push_back(0xdeadbeef);

        return cmd->GET_RAW_POINTER_AT(sizeof(unsigned int)*cmdSize);   ///<< How can I do this?
    }

The concept is that I add values to the vector to make space, but the other library modifies them directly.

If I cannot do this ill have to consider allocating temporary raw memory, filling this out with the library and then copying it into my vector, but would like to avoid this if possible.

Is what I want to do possible somehow?

Chris
  • 2,655
  • 2
  • 18
  • 22

2 Answers2

1

So two things:

  1. You can access the contiguous memory of a vector with std::vector::data() or &vec.front().

  2. If you do that in the code shown above, you'll be returning a pointer to data that disappears when the function returns (the vector's destructor will run, and the data will be freed).

Bill Lynch
  • 80,138
  • 16
  • 128
  • 173
  • I meant to make cmd a pointer, I will edit in the pseudo code so loads of people don't comment on it too much, cheers – Chris Jun 02 '14 at 23:17
  • I've never had to do this before and even though I've used vectors for years, oddly enough... I never knew about ::data(), exactly what I need. – Chris Jun 02 '14 at 23:30
1

I assume that clientData is a user-defined value that you have set to be a pointer to a vector that you have allocated somewhere else and have made sure it remains alive in memory while the C library is writing to it. If that is true, you can do this in your callback:

void* theLibraryCallback (void* clientData, unsigned int theLibrarySize)
{
    std::vector<unsigned int> *cmd = reinterpret_cast<std::vector<unsigned int> *>(clientData);
    std::vector<unsigned int>::size_type cmdSize = cmd->size();

    for (int loop=0;loop<theLibrarySize; loop++)
        cmd->push_back(0xdeadbeef);

    return &(*cmd)[cmdSize];
}

You might want to consider using a typedef to make the vector access a little easier to read:

typedef std::vector<unsigned int> uintvec;

void* theLibraryCallback (void* clientData, unsigned int theLibrarySize)
{
    uintvec *cmd = reinterpret_cast<uintvec*>(clientData);
    uintvec::size_type cmdSize = cmd->size();

    for (int loop=0;loop<theLibrarySize; loop++)
        cmd->push_back(0xdeadbeef);

    return &(*cmd)[cmdSize];
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770