directxpass-by-referencedirectx-9

Passing entire struct array to function


I'm delving into C++ and exploring graphics programming, following a tutorial. However, I've encountered an unexpected issue for which I couldn't find any solutions online.

Here's the code snippet:

struct CustomVertex { float x, y, z; unsigned int color; };

void writeToVRAM(CustomVertex *vertices)
{
    ...
    memcpy(pVoid, vertices, size);
    ...
    return;
}

void createShapes()
{
    // Define vertices for a triangle
    CustomVertex vertices[] =
    {
        { -3.0f, 3.0f, 0.0f, 0xFF0000 }, // Red
        { 3.0f, 3.0f, 0.0f, 0x00FF00 },  // Green
        { 0.0f, -3.0f, 0.0f, 0x0000FF }  // Blue
    };
    writeToVRAM(vertices);
}

I'm attempting to pass the entire array of CustomVertex structs as a pointer to the writeToVRAM function. However, I've noticed that if I don't use pointers, the data isn't transferred properly.

I've tried various function signatures:

void writeToVRAM(CustomVertex *vertices)
void writeToVRAM(CustomVertex vertices)
void writeToVRAM(CustomVertex &vertices)
void writeToVRAM(CustomVertex *vertices[])
void writeToVRAM(CustomVertex vertices[])

And calling methods:

writeToVRAM(&vertices);
writeToVRAM(*vertices);
writeToVRAM(vertices);

Edit: Interestingly, when I refactor the code like this:

void writeToVRAM()
{
    CustomVertex vertices[] =
    {
        { -3.0f, 3.0f, 0.0f, 0xFF0000 }, // Red
        { 3.0f, 3.0f, 0.0f, 0x00FF00 },  // Green
        { 0.0f, -3.0f, 0.0f, 0x0000FF }  // Blue
    };
    ...
    memcpy(pVoid, vertices, size);
    ...
    return;
}

Suddenly, it works as expected.

I've exhausted all combinations of pointers and syntax that I could think of, but none have worked. Can anyone provide insight into this peculiar issue?

I've scoured online resources but haven't found anyone else encountering this problem.


Solution

  • Inside of writetovram(), sizeof(verticies) doesn't return what you think it does. You can't get the size of an array from just a pointer. There are TONS of questions on StackOverflow on this issue.

    Your simplest option is to just pass the array size as another parameter, eg:

    struct CUSTOMVERTEX { FLOAT X, Y, Z; DWORD COLOR; };
    
    void writetovram(CUSTOMVERTEX *verticies, int num_verticies)
    {
        ...
        memcpy(pVoid, verticies, sizeof(*verticies) * num_verticies);
        ...
    }
    
    void createshapes() 
    {
        //simple square
        CUSTOMVERTEX verticies[] =
        {
            { -3.0f, 3.0f, 0.0f, D3DCOLOR_XRGB(0, 0, 255), },
            { 3.0f, 3.0f, 0.0f, D3DCOLOR_XRGB(0, 255, 0), },
            { -3.0f, -3.0f, 0.0f, D3DCOLOR_XRGB(255, 0, 0), },
            { 3.0f, -3.0f, 0.0f, D3DCOLOR_XRGB(0, 255, 255), },
    
        };
    
        writetovram(verticies, 4);
        // or:
        // writetovram(verticies, sizeof(verticies)/sizeof(verticies[0]));
        // or:
        // writetovram(verticies, std::size(verticies));
    }
    

    Other options include: