Przekazanie podwójnego wskaźnika na obiekt do funkcji

0

Hej
Piszę sobie małą giereczkę w C++ z wykorzystaniem biblioteki SDL2. I napotkałem problem - chodzi o przekazanie wskaźnika na obiekt do mojej funkcji, wewnątrz której będzie wywołanie funkcji z SDL'a która wymaga wskaźnika na wskaźnik

Jest tam taka funkcja która tworzy okienko i podstawowy renderer:

SDL_CreateWindowAndRenderer(int width, int height, Uint32 window_flags, SDL_Window** window, SDL_Renderer** renderer) //zwraca inta

Udało mi się użyć jej wewnątrz main'a:

int main(int argc, char **argv) {
        //różne zmienne
        SDL_Window *window = nullptr;
	    SDL_Renderer *renderer = nullptr;

        //nudny kod

        int status = SDL_CreateWindowAndRenderer(SCREEN_WIDTH, SCREEN_HEIGHT, 0, &window, &renderer);
	    if (status != 0) {
		    SDL_Quit();
		    return 1;
	    }
}

Musiałem użyć tego & aby SDL_Window** akcpetowało SDL_Window*. Działa dobrze

Jednak chciałbym wywoływać to wewnątrz funkcji init, którą sobie napisałem i która ustawia, tytuł, parametry okienka itp., ale zupełnie nie wiem jak napisać/oznaczyć parametry SDL_Window* oraz SDL_Renderer* do tej funkcji i jak je wywołać aby obiekty zainicjalizowały się poprawnie.

//tak aby ta linia wykonała się poprawnie wewnątrz inita:
int status = SDL_CreateWindowAndRenderer(SCREEN_WIDTH, SCREEN_HEIGHT, 0, &window, &renderer);

Moje próby (dla czytelności pomijam resztę parametrów, bo nie są ważne):

void initSDL(SDL_Window **& window, SDL_Renderer **& renderer)
void initSDL(SDL_Window ** window, SDL_Renderer ** renderer)
void initSDL(SDL_Window *& window, SDL_Renderer *& renderer)

// + próba zmiany sposobu przekazania parametru wewnątrz main'a - robienie dodatkowych wskaźników na ten obiekt, jakieś & przy wywołaniu etc.

Nic nie działa, zawsze jest błąd (status != 0) i okno się nie pojawia

0

A próbowałeś w taki sposób? ;) Polecam przeczytać to co podlinkował @kq wyżej.

void initSDL(SDL_Window *window, SDL_Renderer *renderer)
{
        // ...
        SDL_CreateWindowAndRenderer(SCREEN_WIDTH, SCREEN_HEIGHT, 0, &window, &renderer);
        // ...
}

int main(int argc, char **argv) {
        SDL_Window *window = nullptr;
        SDL_Renderer *renderer = nullptr;

        initSDL(window, renderer);
}

Swoją drogą, jeżeli funkcja SDL_CreateWindowAndRenderer() przyjmuje parametry przez wartość to dlaczego tworzyć obiekty window i renderer dynamicznie? Jest taka niepisana zasada, żeby wskaźników używać tylko wtedy gdy jest to konieczne (albo znacznie poprawi wydajność). Nie widzę reszty kodu, więc może faktycznie konieczne było użycie wskaźników?

Dla zmiennych utworzonych na stosie rozwiązanie mogłoby wyglądac w taki sposób:

void initSDL(const SDL_Window &window, const SDL_Renderer &renderer)
{
        // ...
        SDL_CreateWindowAndRenderer(SCREEN_WIDTH, SCREEN_HEIGHT, 0, window, renderer);
        // ...
}

int main(int argc, char **argv) {
        SDL_Window window;
        SDL_Renderer renderer;

        initSDL(window, renderer);
}

Lub bez **const ** w parametrach initSDL() jeżeli chcesz modyfikować zmienne.

1
Ryżawa Morda napisał(a):

Musiałem użyć tego & aby SDL_Window** akcpetowało SDL_Window*. Działa dobrze

Musiałeś użyć & żeby móc poprawnie korzystać z tych wskaźników po wyjściu z funkcji SDL_CreateWindowAndRenderer.
Gdyby SDL było napisane w C++ to dałoby radę to jakoś bardziej elegancko rozwiązać, a tak to trzeba się bawić z out parameters

elitedangerous napisał(a):

Swoją drogą, jeżeli funkcja SDL_CreateWindowAndRenderer() przyjmuje parametry przez wartość to dlaczego tworzyć obiekty window i renderer dynamicznie? >

Formatowanie posta pewnie zmyliło. Sygnatura wygląda tak:

int SDL_CreateWindowAndRenderer(int            width,
                                int            height,
                                Uint32         window_flags,
                                SDL_Window**   window,
                                SDL_Renderer** renderer)
2

Oj, @tajny_agent mnie wyprzedził ;)

To nie zadziała. Te wskaźniki są parametrami wyjściowymi tej funkcji

int SDL_CreateWindowAndRenderer(int            width,
                                int            height,
                                Uint32         window_flags,
                                SDL_Window**   window,
                                SDL_Renderer** renderer)

https://wiki.libsdl.org/SDL_CreateWindowAndRenderer

Prawie na pewno musi być tak:

void initSDL(SDL_Window **window, SDL_Renderer **renderer)
{
        // ...
        SDL_CreateWindowAndRenderer(SCREEN_WIDTH, SCREEN_HEIGHT, 0, window, renderer);
        // ...
}

int main(int argc, char **argv) {
        SDL_Window *window;
        SDL_Renderer *renderer;

        initSDL(&window, &renderer);
}
0
Ryżawa Morda napisał(a):

Jednak chciałbym wywoływać to wewnątrz funkcji init, którą sobie napisałem i która ustawia, tytuł, parametry okienka itp., ale zupełnie nie wiem jak napisać/oznaczyć parametry SDL_Window* oraz SDL_Renderer* do tej funkcji i jak je wywołać aby obiekty zainicjalizowały się poprawnie.

//tak aby ta linia wykonała się poprawnie wewnątrz inita:
int status = SDL_CreateWindowAndRenderer(SCREEN_WIDTH, SCREEN_HEIGHT, 0, &window, &renderer);

Moje próby (dla czytelności pomijam resztę parametrów, bo nie są ważne):

void initSDL(SDL_Window **& window, SDL_Renderer **& renderer)
void initSDL(SDL_Window ** window, SDL_Renderer ** renderer)
void initSDL(SDL_Window *& window, SDL_Renderer *& renderer)

// + próba zmiany sposobu przekazania parametru wewnątrz main'a - robienie dodatkowych wskaźników na ten obiekt, jakieś & przy wywołaniu etc.

Nic nie działa, zawsze jest błąd (status != 0) i okno się nie pojawia

Początek spoko, ale opis samego problemu strasznie mętny i nawet widać, że niektórzy powyżej skupili się na tym co akurat masz dobrze.
Efekt jest taki, że najlepsze co dostałeś to ogólniki i dopóki nie poprawisz pytania nic lepszego nie dostaniesz.
Zwróć uwagę, że "twoje próby" pokrywają się z prawidłową odpowiedzią, ale nie wiadomo czemu ci nie zadziałało, bo nie widać ważnych szczegółów.

1 użytkowników online, w tym zalogowanych: 0, gości: 1