main.cpp :(.text 0x5f):未定义的引用
main.cpp:(.text+0x5f): undefined reference to
我尝试从SDL指南中编译一些练习。
我这样编译:
g++ -o main main.cpp -I/usr/local/include/SDL2 -L/usr/local/lib -lSDL2
我得到了:
/tmp/cci2rYNF.o: In function `main':
main.cpp:(.text+0x5f): undefined reference to `Game::init(char const*, int, int, int, int, int)'
collect2: error: ld returned 1 exit status
我的代码是:
main.cpp
#include "Game.h"
// our Game object
Game* g_game = 0;
int main(int argc, char* argv[])
{
g_game = new Game();
g_game->init("Chapter 1", 100, 100, 640, 480, 0);
while(g_game->running())
{
g_game->handleEvents();
g_game->update();
g_game->render();
}
g_game->clean();
return 0;
}
game.h
#ifndef __Game__
#define __Game__
#include <SDL.h>
class Game
{
public:
Game() {}
~Game() {}
bool init(const char* title, int xpos, int ypos, int width, int height, int flags);
void render(){}
void update(){}
void handleEvents(){}
void clean(){}
// a function to access the private running variable
bool running() { return m_bRunning; }
private:
SDL_Window* m_pWindow;
SDL_Renderer* m_pRenderer;
bool m_bRunning;
};
#endif // defined(__Game__) */
game.cpp
#include "Game.h"
bool Game::init(const char* title, int xpos, int ypos, int width, int height, int flags)
{
// attempt to initialize SDL
if(SDL_Init(SDL_INIT_EVERYTHING) == 0)
{
std::cout << "SDL init successn";
// init the window
m_pWindow = SDL_CreateWindow(title, xpos, ypos,
width, height, flags);
if(m_pWindow != 0) // window init success
{
std::cout << "window creation successn";
m_pRenderer = SDL_CreateRenderer(m_pWindow, -1, 0);
if(m_pRenderer != 0) // renderer init success
{
std::cout << "renderer creation successn";
SDL_SetRenderDrawColor(m_pRenderer,
255,255,255,255);
}
else
{
std::cout << "renderer init failn";
return false; // renderer init fail
}
}
else
{
std::cout << "window init failn";
return false; // window init fail
}
}
else
{
std::cout << "SDL init failn";
return false; // SDL init fail
}
std::cout << "init successn";
m_bRunning = true; // everything inited successfully, start main loop
return true;
}
void Game::render()
{
SDL_RenderClear(m_pRenderer); // clear the renderer to the draw color
SDL_RenderPresent(m_pRenderer); // draw to the screen
}
void Game::clean()
{
std::cout << "cleaning gamen";
SDL_DestroyWindow(m_pWindow);
SDL_DestroyRenderer(m_pRenderer);
SDL_Quit();
}
void Game::handleEvents()
{
SDL_Event event;
if(SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_QUIT:
m_bRunning = false;
break;
default:
break;
}
}
}
c和c 具有"编译单元"的概念,这是调用编译器和所有代码#include
s。
GCC,MSVC和大多数编译器将为每个编译单元生成一个中间的"对象文件"(.O或.OBJ)。然后,必须将它们与任何库一起组合在一起,以形成最终的可执行文件,以称为"链接"的步骤。
。使用GCC,有几种方法可以做到这一点。单个命令:
g++ -o app.exe file1.cpp file2.cpp
此commiles file1.cpp和file2.cpp分别(每个还是一个汇编单元)以对象文件,然后将结果对象文件链接到可执行的名为" app.exe"的可执行文件(您不需要.exe扩展,我只是为了清楚地使用它)
或多个命令:
g++ -o file1.o -c file1.cpp
g++ -o file2.o -c file2.cpp
g++ -o app.exe file1.o file2.o
这单独执行每个CPP上的汇编步骤,然后执行一个单独的链路步骤,并用" G "作为每个步骤的前端。注意前两行中的-c
,该行告诉您要将C/C 源编译为.Object。第三行,编译器前端认识到您要它编译对象文件,并确定要执行链接步骤。
对于小项目来说,第一种方法通常是最容易的,当您使用任何类型的构建系统并且事物开始变得复杂时,第二种方法很有用。
您没有编译Game.cpp
。尝试:
g++ -o main main.cpp Game.cpp -I/usr/local/include/SDL2 -L/usr/local/lib -lSDL2
问题是,尽管您在main.cpp
中的#include
D Game.h
,但它引用了Game.cpp
中定义的功能。如果也不对此进行编译,链接器没有制作可执行文件所需的定义。
相关文章:
- 对C宏的未定义引用,但在定义它时会出现重新定义错误
- 编译时的 CImg 库返回对"__imp_SetDIBitsToDevice"的未定义引用
- 对Py_Initialize()的未定义引用
- 使用mysql c++连接器的未定义引用
- 对 Scalar ::Scalar() 的未定义引用
- 对复制 CTOR 和 CTOR 的未定义引用
- 对显式实例化的模板函数的未定义引用
- TensorRT (C++ API) 对"createNvOnnxParser_INTERNAL"的未定义引用
- 2个模板化类的非模板友元函数未定义引用错误
- 编译 libfluid 样本控制器时对"event_base_del_virtual"的未定义引用
- 获取对function_name的未定义引用
- 对 'std::thread::_M_start_thread CMake 的未定义引用进行基准测试
- 对结构方法的未定义引用
- 使用内联函数 c++ 的未定义引用
- 对 CMake 中'cudaRegisterLinkedBinary'链接错误的未定义引用?
- 对 DLOPEN 的未定义引用
- QT C++中对全局变量的未定义引用
- 快速数学导致对"__pow_finite"的未定义引用
- 对 boost::system::d etail::system_category_instance 的未定义引用,从
- OpenCV 3.4.3 中对 'cv::String::d eallocate()' 错误的未定义引用