основной уже определен в main.obj - PullRequest
3 голосов
/ 03 июля 2019

Я пытаюсь настроить проект SDL с помощью Visual Studio 2019, используя эту статью:

https://www.wikihow.com/Set-Up-SDL-with-Visual-Studio

, но компилятор выдает мне ошибки с одним или несколькими кратно определенныминайденные символы 'и
' _main уже определены в main.obj '.

main.obj - это файл в папке отладки моего проекта, но когда я пытаюсь удалить его или всю папку отладки, VS воссоздаетэто когда я запускаю проект.

Я читал, что в c ++ не может быть больше одной основной функции, но я не могу открыть файл main.obj, и я действительно не хочу удалять однув main.cpp

Вот код, который я запускаю, и спасибо за вашу помощь!

#include "SDL.h"
#include <stdio.h>

int main(int argc, char* argv[])
{
    SDL_Init(SDL_INIT_VIDEO);

    SDL_Window* window = SDL_CreateWindow
    ("An SDL2 window", // window's title
        10, 25, // coordinates on the screen, in pixels, of the window's upper left corner
        640, 480, // window's length and height in pixels  
        SDL_WINDOW_OPENGL);

    SDL_Delay(3000); // window lasts 3 seconds
    SDL_DestroyWindow(window);
    SDL_Quit();
    return 0;
}

Ответы [ 2 ]

1 голос
/ 03 июля 2019

Рад знать, что это работает сейчас.Возможно, у вас была грязная файловая структура с вашей предыдущей установкой SDL.В любом случае, я думаю, что было бы интересно показать, как можно удалить зависимость SDL из вашего файла main.cpp, чтобы избежать подобных проблем в будущем.

Сначала давайте рассмотрим пример в вашем вопросе.Пример не очень полезен на практике, но я покажу лучшую версию после.

Основная идея - скрыть все, что связано с SDL, от ваших main.cpp и заголовков.

1.Простой пример

// MySDL.h - NO SDL STUFF
class MySDL
{
public:
    MySDL() = default; // or whatever you need
    void runtest() const; // here we'll run the 3sec window
};

Теперь мы можем поместить все наши SDL в файл cpp:

// MySDL.cpp
#include "MySDL.h"
#include "SDL.h" // HERE WE INCLUDE SDL

void MySDL::runtest()
{
    SDL_Init(SDL_INIT_EVERYTHING);
    SDL_Window* window = SDL_CreateWindow("yee haw", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 600, 400, SDL_WINDOW_SHOWN);

    SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, 0);

    SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255);

    SDL_RenderClear(renderer);
    SDL_RenderPresent(renderer);

    SDL_Delay(3000);
}

Нет SDL, включенного в main.cpp, мы просто включаем наш SDLинтерфейс MySDL.h.

// Now you can use your SDL interface like this
int main(int, char* [])
{
    MySDL sdl;
    sdl.runtest();

    return 0;
}

2.Лучшая версия

Тем не менее, вы обычно хотите что-то более изощренное, чем окно, которое исчезает через 3 секунды.Поэтому вы можете хранить членов класса, что зависит от SDL.Но тогда вам потребуется #include "SDL.h" в заголовочном файле MySDL.h, что вызовет те же проблемы, что описаны в вашем вопросе и комментариях.Чтобы удалить эту зависимость, мы можем использовать идиому pimpl.

Файл заголовка теперь содержит указатель на нашу реализацию SDL.Эта реализация SDL будет определена в файле cpp для удаления зависимости SDL.

// MySDL.h
class MySDL
{
public:
    MySDL() = default; // or whatever you need
    ~MySDL();

    void doSmthWithYourWindow(/*args*/);

private:
    // pointer to our SDLImplementation (defined in cpp file)
    class SDLImplementation;
    std::unique_ptr<SDLImplementation> _sdl;
};

В нашем файле cpp мы определяем SDLImplementation, и MySDL имеет доступ к этой реализации через _sdl указатель.

// MySDL.cpp
#include "MySDL.h"
#include "SDL.h"

// here we can store class members which depend on SDL
struct MySDL::SDLImplementation
{
    SDLImplementation()
    {
        SDL_Init(SDL_INIT_EVERYTHING);
        _window = SDL_CreateWindow("yee haw", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 600, 400, SDL_WINDOW_SHOWN);
        _renderer = SDL_CreateRenderer(_window, -1, 0);
        SDL_SetRenderDrawColor(_renderer, 0, 255, 0, 255);

        SDL_RenderClear(_renderer);
        SDL_RenderPresent(_renderer);
    }

    // functionality of your SDL implementation
    void turnWindowUpsideDown() { /* _window->turnUpsideDown(); */ }

    // members depending on SDL
    SDL_Window* _window;
    SDL_Renderer* _renderer;
};

MySDL::~MySDL() = default;

void MySDL::doSmthWithYourWindow(/*args*/)
{
    // here we have access to our SDL implementation
    _sdl->turnWindowUpsideDown();
}

Как и прежде, мы только включаем наш MySDL.h интерфейс в файл main.cpp.

int main(int, char* [])
{
    MySDL sdl;
    sdl.doSmthWithYourWindow();
    return 0;
}
0 голосов
/ 03 июля 2019

Так что я закончил тем, что удалил SDL и полностью перезапустил другой учебник, связанный здесь:

https://www.youtube.com/watch?v=QQzAHcojEKg

Не совсем уверен, в чем разница, но это сработало.В любом случае, спасибо за вашу помощь, и я поставлю новый код здесь.

#include "SDL.h"

int main(int argc, char* argv[])
{
    SDL_Init(SDL_INIT_EVERYTHING);
    SDL_Window* window = SDL_CreateWindow("yee haw", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 600, 400, SDL_WINDOW_SHOWN);

    SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, 0);

    SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255);

    SDL_RenderClear(renderer);
    SDL_RenderPresent(renderer);

    SDL_Delay(3000);

    return 0;
}
...