【问题标题】:Able to include cpp.... but not header? Whats going on?能够包含 cpp .... 但不包含标题?这是怎么回事?
【发布时间】:2014-06-13 23:02:04
【问题描述】:

我觉得我在 C++ 中误解了一个大概念 (不能买任何书。) 我在这方面找不到其他任何东西,如果出现隐藏在互联网某个不起眼部分的东西,我很抱歉。 最近,当我发现一种为 sdl 创建应用程序包装器的新方法时,我一直在尝试使用 SDL。但是当把它分成一个单独的 cpp 和头文件时......事情发生了。

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);
}

标题:

//
//  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__) */

现在,你看,当我包含 cpp 文件并执行以下操作时: app_sdl app; return app.run(640, 480, APPTITLE); 在我的主整数中,一切运行良好。但是当我包含 HEADER 文件时,会发生这种情况:

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)

有人知道这里发生了什么吗?我该怎么办?

【问题讨论】:

    标签: c++ file include undefined


    【解决方案1】:

    您可能知道,包含 cpp 文件不是正确的做法,即使它似乎可以解决此问题。

    当您忘记将源文件添加到编译命令时,就会发生类似您的错误。

    我从未使用过 xcode,但快速谷歌搜索导致this page 这表明:

    1. 检查缺少哪些符号
    2. 目标->构建阶段->编译源代码
    3. 如果缺少的源文件未列出,请添加它们
    4. command+b 再次编译源代码

    【讨论】:

    • 好的,事实证明它修复了它。但是为什么包括 cpp 是一种解决方法?这是链接问题吗?
    • 这是一个链接问题。如果您不编译源文件,那么调用者将无法链接到任何内容。包含文件与将包含文件的内容写入包含它的文件中相同。所以包含的源文件确实被编译了。只是不在它自己的编译单元中,而是在包含它的编译单元中。
    猜你喜欢
    • 1970-01-01
    • 2014-04-06
    • 1970-01-01
    • 1970-01-01
    • 2016-02-15
    • 1970-01-01
    • 2013-11-22
    • 2022-11-27
    • 1970-01-01
    相关资源
    最近更新 更多