0

A bitmap struct I translate in another function is set to NULL after the function returns

the function :


HRESULT RessourcesLoader::decode(LPCWSTR name,ID2D1Bitmap* bitmap1) {
    int hr = S_OK;
    hr = LoadFile(name, bitmap1);
    assert(SUCCEEDED(hr));

    hr = rendertarget->CreateBitmapFromWicBitmap(wicConverter, NULL, &bitmap1);
    assert(SUCCEEDED(hr));

return hr;

called here :


ID2D1Bitmap* bmp1=NULL;
ID2D1Bitmap* bmp2=NULL;


rl->decode(L"Menu_corner.png", bmp1);

rl->decode(L"Menu_side.png", bmp2);

(inside the function hr is S_OK and the struct have all in it, once the function return the pointers are NULL) is it a scope issue ?

Frank Boyne
  • 4,400
  • 23
  • 30
AlexB
  • 3
  • 3
  • If you want to get the pointer assignment out of `decode` function you must specify the function like `HRESULT RessourcesLoader::decode(LPCWSTR name,ID2D1Bitmap** bitmap1)`. – Mathias Schmid Oct 20 '19 at 22:33

2 Answers2

2

You are passing a copy of your bitmap pointers to your function. Your function modifies the copies, but that has no effect on the original pointers from which the copies were made.

If you want to modify the pointers you pass to your function, you need to pass either a reference or pointer to them:

HRESULT RessourcesLoader::decode(LPCWSTR name, ID2D1Bitmap*& bitmap1) {
                                                        // ^----- Pass by reference
    int hr = S_OK;
    hr = LoadFile(name, bitmap1);
    assert(SUCCEEDED(hr));

    hr = rendertarget->CreateBitmapFromWicBitmap(wicConverter, NULL, &bitmap1);
    assert(SUCCEEDED(hr));

    return hr;
}
Miles Budnek
  • 28,216
  • 2
  • 35
  • 52
0

Remember that C++ parameters like ID2D1Bitmap* bitmap1 are passed by value. That means you have two completely separate (and almost unrelated) variables bmp1 and bitmap1. The only relationship the two variables have is that bitmap1 starts life with the same value that bmp1 had when decode was called - i.e., NULL.

Your decode logic calls CreateBitmapFromWicBitmap passing in the address of bitmap1and CreateBitmapFromWicBitmap carefully fills bitmap1 with the address of the newly created bitmap. But that doesn't affect bmp1 at all. So bmp1 remains set to null. You can check this for yourself by placing a breakpoint on return hr and then looking at the contents of bmp1 and bitmap1.

If you want Decode to change the contents of bmp1 you need to pass the address of bmp1 to decode not the contents. That means bitmap1 should be type ID2D1Bitmap ** and decode should be called like this... rl->decode(L"Menu_corner.png", &bmp1);

Update

Several comments pointed out that I was rather careless in saying "C++ parameters are passed by value", I've reworded the text above to be more focused.

The comments also point out that that C++ parameters can be passed by reference as well as by value. In the case of the decode function by using the syntax ID2D1Bitmap*& bitmap1.

I have to confess I'm somewhat ambivalent about the relative merits of ID2D1Bitmap** bitmap1 and ID2D1Bitmap*& bitmap1. But that may say more about my personal biases than about anything else.

Frank Boyne
  • 4,400
  • 23
  • 30
  • 1
    C++ has pass-by-reference natively, there's no reason to use the old C hack of simulating it with pass-by-pointer – M.M Oct 20 '19 at 22:49
  • 1
    *Remember that C++ parameters are passed by value.* -- This is true in `C`, not true in `C++`. C++ has both pass by value and pass by reference, since reference types do not exist in `C`. – PaulMcKenzie Oct 21 '19 at 00:02
  • @M.M +1 for keeping me honest! :-) There's a tension between discussing what's wrong with the code as presented versus discussing alternative ways of achieving the intended outcome. But yes, I got the balance wrong. I should have mentioned reference variables somewhere in my answer. – Frank Boyne Oct 21 '19 at 00:18
  • @PaulMcKenzie Fair point. I should have expressed myself more carefully. – Frank Boyne Oct 21 '19 at 00:22