سؤال

I feel like I'm misunderstanding a big concept here in c++ (Can't buy any books.) I couldn't find anything else on this, sorry if something hidden in an obscure part of the internet turns up. I've been trying to work with SDL lately when I found a new interesting way of creating an application wrapper for sdl. But when separating it into a separate cpp and header file... stuff happens.

C++:

//
//  AppSdl.cpp
//  sdlgaim
//
//  Created by Home on 28/4/14.
//  Copyright (c) 2014 hyperum. All rights reserved.
//

#include "AppSdl.h"

app_sdl::app_sdl() :
_running(false)
{
}

app_sdl::~app_sdl()
{
    destroy();
}

int app_sdl::init(int width, int height, const char *title)
{
    // Initialize the SDL library.
    if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0)
    {
        fprintf(stderr, "SDL_Init() failed: %s\n", SDL_GetError());
        return APP_FAILED;
    }

    win = SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_SHOWN);
    renderer = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);

    // Success.
    return APP_OK;
}

void app_sdl::destroy()
{
    if (win)
    {
        SDL_DestroyWindow(win);
        SDL_DestroyRenderer(renderer);
        SDL_Quit();
    }
}

int app_sdl::run(int width, int height, const char *title)
{
    // Initialize application.
    int state = init(width, height, title);
    if (state != APP_OK) return state;

    // Enter to the SDL event loop.
    SDL_Event ev;
    _running = true;

    while (SDL_WaitEvent(&ev))
    {
        onEvent(&ev);
        Render();

        if (_running == false)
        {
            break;
        }
    }

    // Success.
    return APP_OK;
}

void app_sdl::onEvent(SDL_Event* ev)
{
    switch (ev->type)
    {
        case SDL_QUIT:
            _running = false;
            break;

        case SDL_KEYDOWN:
        {

            switch (ev->key.keysym.sym)
            {
                case SDLK_ESCAPE:
                    _running = false;
                    break;
            }
        }
    }
}

void app_sdl::Render()
{
    SDL_Rect r;
    int w,h;
    SDL_GetWindowSize(win, &w, &h);

    r.w = 200;
    r.h = 200;
    r.x = w/2-(r.w/2);
    r.y = h/2-(r.h/2);


    //
    SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0, 0xff);
    SDL_RenderClear(renderer);

    SDL_SetRenderDrawColor(renderer, 0xff, 0xff, 0, 0xff);
    SDL_RenderFillRect(renderer, &r);
    SDL_RenderPresent(renderer);
}

Header:

//
//  AppSdl.h
//  sdlgaim
//
//  Created by Home on 28/4/14.
//  Copyright (c) 2014 hyperum. All rights reserved.
//

#ifndef __sdlgaim__AppSdl__
#define __sdlgaim__AppSdl__

#include <iostream>
#include <SDL2/SDL.h>
struct app_sdl
{

    app_sdl();
    ~app_sdl();



    // Application state (just convenience instead of 0, 1, ...).


    enum APP_STATE
    {
        APP_OK = 0,
        APP_FAILED = 1
    };

    // Destroy application, called by destructor, don't call manually.
    void destroy();

    int init(int width, int height, const char *title);

    // Run application, called by your code.
    int run(int width, int height, const char *title);

    // Called to process SDL event.
    void onEvent(SDL_Event* ev);

    // Called to render content into buffer.
    void Render();

    // Whether the application is in event loop.
    bool _running;
    SDL_Window *win;
    SDL_Renderer *renderer;
};


#endif /* defined(__sdlgaim__AppSdl__) */

Now, you see, when I include the cpp file and do this: app_sdl app; return app.run(640, 480, APPTITLE); in my main integer, everything runs fine. But when I include the HEADER file instead, this happens:

Undefined symbols for architecture x86_64:
  "app_sdl::run(int, int, char const*)", referenced from:
      _main in main.o
  "app_sdl::app_sdl()", referenced from:
      _main in main.o
  "app_sdl::~app_sdl()", referenced from:
      _main in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Anyone knows what's happening here? And what I should do?

هل كانت مفيدة؟

المحلول

As you may know, including a cpp file is not the right thing to do even if it seems to work around this problem.

Error like yours occurs when you forget to add the source file to the compile command.

I've never used xcode, but quick googling resulted in this page which suggests:

  1. examine which symbols are missing
  2. target->build phases->compile source
  3. add the missing source files if they are not listed
  4. command+b to compile the source code again
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top