error LNK2019: 无法解析的外部符号 "private: __thiscall Example::Example(char const *)" (?

fordawn 2012-03-18 12:09:40
error LNK2019: 无法解析的外部符号 "private: __thiscall Example::Example(char const *)" (??0Example@@AAE@PBD@Z),该符号在函数 "public: static class GL_Application * __cdecl GL_Application::Create(char const *)" (?Create@GL_Application@@SAPAV1@PBD@Z) 中被引用
example.obj : error LNK2019: 无法解析的外部符号 _auxWireTeapot@8,该符号在函数 "public: virtual void __thiscall Example::Draw(void)" (?Draw@Example@@UAEXXZ) 中被引用
1>E:\!myproject\mycpp\OOGLFrame\Debug\OOGLFrame.exe : fatal error LNK1120: 2 个无法解析的外部命令

我照着书上写的程序,结果写完以后出来这个错误了。
请问是什么原因呢?
...全文
623 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
Eleven 2012-03-20
  • 打赏
  • 举报
回复
函数没定义,只有声明,没有实现部分
fordawn 2012-03-20
  • 打赏
  • 举报
回复


//GLWindows.h

#ifndef _GL_WINDOW_H_
#define _GL_WINDOW_H_

#include <Windows.h>

class GL_Window
{
public:

GL_Window(); //构造函数
bool Create(const char *window_title,bool full_screen,
const char *class_name,HINSTANCE h_Instance,LPVOID lpParam); //创建窗口
void Destroy(); //删除窗口
bool ChangeScreenSetting(); //改变窗口显示设置
void ReshapeGL(); //当窗口大小变化,通知GL
void SwapBuffers(){::SwapBuffers(m_hDC);} //

/*设置窗口左上角位置*/
void SetPosX(int x){m_WindowPosX=x;}
void SetPosX(unsigned short x){SetPosX((signed short)x);}
void SetPosY(int y){m_WindowPosY=y;}
void SetPosY(unsigned short y){SetPosX((signed short)y);}

/*返回窗口的大小*/
int GetWidth(){return m_WindowWidth;}
int GetHeight(){return m_WindowHeight;}

/*设置窗口的大小*/
void SetWidth(int width){m_WindowWidth=width;}
void SetHeight(int height){m_WindowHeight=height;}

/*返回窗口左上角的位置*/
int GetPosX(){return m_WindowPosX;}
int GetPosY(){return m_WindowPosY;}

/*设置窗口的颜色位深*/
void SetHiColor(){m_BitsPerPixel=16;}
void SetTrueColor(){m_BitsPerPixel=32;}

/*重载运算符*/
operator HWND(){return m_hWnd;}

private:
HWND m_hWnd; //窗口句柄
HDC m_hDC; //设备描述表
HGLRC m_hRC; //OpenGL渲染描述表

int m_WindowPosX; //窗口左上角X
int m_WindowPosY; //Y
int m_WindowWidth; //窗口宽度
int m_WindowHeight; //高度
int m_ScreenWidth; //全屏宽度
int m_ScreenHeight; //高度
int m_BitsPerPixel; //颜色位深
bool m_IsFullScreen; //是否全屏
};

#endif



//example.cpp

#include "example.h"

#include <gl\glew.h>
#include <gl\GLAUX.H>

GL_Application* GL_Application::Create(const char *class_name)
{
Example *example=new Example(class_name);
return reinterpret_cast<GL_Application*>(example);
}

bool Example::Initialize()
{
glClearColor(0.0f,0.0f,0.0f,0.5f);
glClearDepth(1.0f);
glDepthFunc(GL_LEQUAL);
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_SMOOTH);
glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
ResizeDraw(true);

return true;
}

void Example::Draw()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();

glTranslatef(0.0f,0.0f,-7.0f);
glRotatef(m_Angle,0.0f,1.0f,0.0f);
glColor3f(0.0f,0.0f,1.0f);
auxWireTeapot(2.0);

glFlush();
}

void Example::Update(DWORD milliseconds)
{
if(m_Keys.IsPressed(VK_ESCAPE)==true)
{
TerminateApplication();
}

if(m_Keys.IsPressed(VK_F1)==true)
{
ToggleFullscreen();
}

m_Angle+=(float)(milliseconds)/15.0f;
}

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
int ret=-1;

GL_Application *appl=GL_Application::Create("OP!fyzzy!");

if(appl!=0)
{
ret=appl->Main(hInstance,hPrevInstance,lpCmdLine,nCmdShow);
delete appl;
}
else
{
MessageBox(HWND_DESKTOP,"创建程序出错","Error",MB_OK | MB_ICONEXCLAMATION);
}

return ret;
}

int GL_Application::Main(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
WNDCLASSEX windowClass;
ZeroMemory(&windowClass,sizeof(WNDCLASSEX));
windowClass.cbSize=sizeof(WNDCLASSEX);
windowClass.style=CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
windowClass.lpfnWndProc=(WNDPROC)(WindowProc);
windowClass.hInstance=hInstance;
windowClass.hbrBackground=(HBRUSH)(COLOR_APPWORKSPACE);
windowClass.hCursor=LoadCursor(NULL,IDC_ARROW);
windowClass.lpszClassName=m_ClassName;

if(RegisterClassEx(&windowClass)==0)
{
MessageBox(HWND_DESKTOP,"注册窗口失败","Error",MB_OK | MB_ICONEXCLAMATION);
return -1;
}

if(MessageBox(HWND_DESKTOP,"全屏?","?",MB_YESNO | MB_ICONQUESTION)==IDNO)
{
m_CreateFullScreen=false;
}

while(m_IsProgramLooping)
{
if(m_Window.Create("OO",m_CreateFullScreen,m_ClassName,hInstance,this)==true)
{
if(Initialize()==false)
{
TerminateApplication();
}
else
{
MSG msg;
bool isMessagePumpActive=true;
m_LastTickCount=GetTickCount();
m_Keys.Clear();
while(isMessagePumpActive==true)
{
if(PeekMessage(&msg,m_Window,0,0,PM_REMOVE)!=0)
{
if(msg.message!=WM_QUIT)
{
DispatchMessage(&msg);
}
else
{
isMessagePumpActive=false;
}
}
else
{
if(m_IsVisible==false)
{
WaitMessage();
}
else
{
DWORD tickCount=GetTickCount();
Update(tickCount-m_LastTickCount);
m_LastTickCount=tickCount;
Draw();
m_Window.SwapBuffers();
}
}
}
}
DeInitialize();
m_Window.Destroy();
}
else
{
MessageBox(HWND_DESKTOP,"GL窗口错误","ERROR",MB_OK | MB_ICONEXCLAMATION);
}
}
UnregisterClass(m_ClassName,hInstance);
return 0;

}

LRESULT CALLBACK WindowProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
LONG user_data=GetWindowLong(hWnd,GWL_USERDATA);
if(user_data==0)
{
if(uMsg==WM_CREATE)
{
CREATESTRUCT *creation=reinterpret_cast<CREATESTRUCT*>(lParam);
GL_Application *appl=reinterpret_cast<GL_Application*>(creation->lpCreateParams);
SetWindowLong(hWnd,GWL_USERDATA,reinterpret_cast<LONG>(appl));
appl->m_IsVisible=true;
return 0;
}
}
else
{
GL_Application *appl=reinterpret_cast<GL_Application*>(user_data);
return appl->Message(hWnd,uMsg,wParam,lParam);

}
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}



//GLWindows.cpp

#include "GLWindows.h"
#include <gl\glut.h>

/*构造函数*/
GL_Window::GL_Window()
{
m_WindowPosX=0;
m_WindowPosY=0;
m_WindowWidth=800;
m_WindowHeight=600;
m_ScreenWidth=1366;
m_ScreenHeight=769;
m_BitsPerPixel=32;
m_IsFullScreen=false;

m_hWnd=0;
m_hDC=0;
m_hRC=0;
}

/*创建Windows窗口*/
bool GL_Window::Create(const char *window_title,bool full_screen,const char *class_name,
HINSTANCE h_Instance,LPVOID lpParam)
{
m_IsFullScreen=full_screen;

PIXELFORMATDESCRIPTOR pfd=
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL |
PFD_STEREO |
PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
m_BitsPerPixel,
0,0,0,0,0,0,
0,
0,
0,
0,0,0,0,
32,
0,
0,
PFD_MAIN_PLANE,
0,
0,0,0
};

DWORD windowStyle=WS_OVERLAPPEDWINDOW;
DWORD windowExtendedStyle=WS_EX_APPWINDOW;

if(m_IsFullScreen==true)
{
if(ChangeScreenSetting()==false)
{
MessageBox(HWND_DESKTOP,"全屏错误,窗口运行","e",MB_OK | MB_ICONEXCLAMATION);
m_IsFullScreen=false;
}
else
{
ShowCursor(false);
windowStyle=WS_POPUP;
windowExtendedStyle|=WS_EX_TOPMOST;
}
}

/*调整窗口大小*/
RECT windowRect={GetPosX(),GetPosY(),GetPosX()+GetWidth(),GetPosY()+GetHeight()};

if(m_IsFullScreen==false)
{
AdjustWindowRectEx(&windowRect,windowStyle,0,windowExtendedStyle);

if(windowRect.left<0)
{
windowRect.right-=windowRect.left;
windowRect.left=0;
}
if(windowRect.top<0)
{
windowRect.bottom-=windowRect.top;
windowRect.top=0;
}
}

/*创建窗口*/
m_hWnd=CreateWindowEx(windowExtendedStyle,
class_name,
window_title,
windowStyle,
windowRect.left,windowRect.top,
windowRect.right-windowRect.left,
windowRect.bottom-windowRect.top,
HWND_DESKTOP,
0,
h_Instance,
lpParam);

while(m_hWnd!=0)
{
m_hDC=GetDC(m_hWnd);
if(m_hDC==0)
{
break;
}

GLuint PixelFormat=ChoosePixelFormat(m_hDC,&pfd);
if(PixelFormat==0)
{
break;
}

if(SetPixelFormat(m_hDC,PixelFormat,&pfd)==false)
{
break;
}

m_hRC=wglCreateContext(m_hDC);
if(m_hRC==0)
{
break;
}

if(wglMakeCurrent(m_hDC,m_hRC)==false)
{
break;
}

ShowWindow(m_hWnd,SW_NORMAL);
ReshapeGL();
return true;
}

Destroy();
return false;
}

/*改变窗口的显示设置*/
bool GL_Window::ChangeScreenSetting()
{
DEVMODE dmScreenSettings;
ZeroMemory(&dmScreenSettings,sizeof(DEVMODE));
dmScreenSettings.dmSize=sizeof(DEVMODE);
dmScreenSettings.dmPanningWidth=GetWidth();
dmScreenSettings.dmPanningHeight=GetHeight();
dmScreenSettings.dmBitsPerPel=m_BitsPerPixel;
dmScreenSettings.dmFields=DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;

//改变显示模式
if(ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL)
{
return false;
}

return true;
}

/*窗口大小改变时,通知OpenGL*/
void GL_Window::ReshapeGL()
{
GLsizei width=GetWidth();
GLsizei height=GetHeight();
glViewport(0,0,width,height); //重新设置视口
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,1.0f,100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

/*删除OpenGL窗口*/
void GL_Window::Destroy()
{
if(m_hWnd!=0)
{
if(m_hDC!=0)
{
wglMakeCurrent(m_hDC,0);
if(m_hRC!=0)
{
wglDeleteContext(m_hRC);
m_hRC=0;
}
ReleaseDC(m_hWnd,m_hDC);
m_hDC=0;
}
DestroyWindow(m_hWnd);
m_hWnd=0;
}

if(m_IsFullScreen)
{
ChangeDisplaySettings(NULL,0);
ShowCursor(true);
}
}




这些是全部的代码了,文件分的有点乱,一共是五个,那个构造函数实在不会写了 - -!麻烦大家帮忙看看了。
fordawn 2012-03-20
  • 打赏
  • 举报
回复

//example.h
#ifndef _EXAMPLE_H_
#define _EXAMPLE_H_

#include "GLApplication.h"

class Example:GL_Application
{
public:
bool Initialize(); //所有的初始化
void DeInitialize(); //所有的卸载
void Update(DWORD milliseconds); //所有的更新
void Draw(); //所有的绘制

private:
friend class GL_Application;
Example(const char *class_name);

float m_Angle;
};

#endif



//GLApplication.h
#ifndef _GLAPPLICATION_H_
#define _GLAPPLICATION_H_

#include <Windows.h>
#include "GLWindows.h"

class Keys
{
public:
Keys(){Clear();}
void Clear(){ZeroMemory(&m_KeyDown,sizeof(m_KeyDown));} //清除所有按键信息
bool IsPressed(unsigned int key){return (key<MAX_KEYS)?(m_KeyDown[key]==true):false;} //判断某个键按下
void SetPressed(unsigned int key){if(key<MAX_KEYS)m_KeyDown[key]=true;}
void SetReleased(unsigned int key){if(key<MAX_KEYS)m_KeyDown[key]=false;}

private:
static const unsigned int MAX_KEYS=256;
bool m_KeyDown[MAX_KEYS];
};

class GL_Application
{
public:
static GL_Application *Create(const char *class_name);
virtual ~GL_Application(){};

protected:
virtual bool Initialize()=0;
virtual void DeInitialize()=0;
virtual void Update(DWORD milliseconds)=0; //OpenGl程序更新
virtual void Draw()=0; //绘制场景

/*通用函数*/
void ToggleFullscreen(); //切换全屏/窗口
void TerminateApplication(); //结束程序
void ResizeDraw(bool enable){m_ResizeDraw=enable;} //设置在窗口改变大小的时候,可以绘制

Keys m_Keys;
GL_Application(const char *class_name); //构造函数

private:
friend int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow);
int Main(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int cCmdLine);
friend LRESULT CALLBACK WindowProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
LRESULT Message(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
static const UINT WM_TOGGLEFULLSCREEN=(WM_USER+1);

GL_Window m_Window;
const char *m_ClassName;
bool m_IsProgramLooping;
bool m_CreateFullScreen;
bool m_IsVisible;
bool m_ResizeDraw;
DWORD m_LastTickCount;
};

/*构造函数*/
GL_Application::GL_Application(const char *class_name)
{
m_ClassName=class_name;
m_IsProgramLooping=true;
m_CreateFullScreen=true;
m_IsVisible=false;
m_ResizeDraw=false;
m_LastTickCount=0;
}

/*窗口切换函数*/
void GL_Application::ToggleFullscreen()
{
PostMessage(m_Window,WM_TOGGLEFULLSCREEN,0,0); //发送自定的切换消息
}

/*结束程序*/
void GL_Application::TerminateApplication()
{
PostMessage(m_Window,WM_QUIT,0,0);
m_IsProgramLooping=false; //停止程序循环
}

/*消息循环*/
LRESULT GL_Application::Message(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
switch(uMsg)
{
case WM_SYSCOMMAND:
switch(wParam)
{
case SC_SCREENSAVE:
case SC_MONITORPOWER:
return 0;
break;
}
break;

case WM_CLOSE:
TerminateApplication();
return 0;
break;

case WM_EXITMENULOOP:
case WM_EXITSIZEMOVE:
m_LastTickCount=GetTickCount(); //更新计数器的值
return 0;
break;

case WM_MOVE:
m_Window.SetPosX(LOWORD(lParam)); //更新鼠标的坐标
m_Window.SetPosY(HIWORD(lParam));
return 0;
break;

case WM_PAINT:
if(m_ResizeDraw==true) //如果需要重绘
{
m_Window.ReshapeGL();
Draw();
m_Window.SwapBuffers();
}
break;

case WM_SIZING: //窗口正在改变大小
{
RECT *rect=(RECT*)lParam;
m_Window.SetWidth(rect->right-rect->left); //设置窗口宽度
m_Window.SetHeight(rect->bottom-rect->top);
return TRUE;
}
break;

case WM_SIZE: //窗口改变大小后
{
switch(wParam)

case SIZE_MINIMIZED:
m_IsVisible=false;
return 0;
break;

case SIZE_MAXIMIZED:
case SIZE_RESTORED:
m_IsVisible=true;
m_Window.SetWidth(LOWORD(lParam));
m_Window.SetHeight(HIWORD(lParam));
m_Window.ReshapeGL();
m_LastTickCount=GetTickCount();
return 0;
break;
}
break;

case WM_KEYDOWN: //更新按键信息
m_Keys.SetPressed(wParam);
return 0;
break;

case WM_KEYUP:
m_Keys.SetReleased(wParam);
return 0;
break;

case WM_TOGGLEFULLSCREEN:
m_CreateFullScreen=!m_CreateFullScreen;
PostMessage(hWnd,WM_QUIT,0,0);
break;
}

return DefWindowProc(hWnd,uMsg,wParam,lParam);
}

#endif

fordawn 2012-03-20
  • 打赏
  • 举报
回复
我一看,构造函数果然没定义……不过Draw是有定义的,我把构造函数定义下试试看
hdg3707 2012-03-18
  • 打赏
  • 举报
回复
你照着书写的,书上未必是完全的工程:
1.未定义这两个函数.
2.这两个函数是在一个DLL里,你没加上对应的lib这个库文件
向立天 2012-03-18
  • 打赏
  • 举报
回复
从错误看
应该是这两个函数没定义
LittleCommit 2012-03-18
  • 打赏
  • 举报
回复
Example::Example(char const *);
Example::Draw(void);
这两个函数是否已经实现(是否有函数体)?

19,469

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧