2017-01-23 46 views
1

我對使用OpenGL很新穎。我試圖運行的程序是由我的教授提供的,所以我實際上沒有寫任何程序,我在運行程序時遇到問題。該程序假設只是在黑色屏幕上製作一個白色正方形。我正在使用mac Sierra 10.12.2。此外,我已經將部署目標更改爲10.8,因爲在晚些時候編譯的錯誤。現在,當我嘗試構建並在xcode中運行時,我得到2個錯誤。未找到架構x86_64的符號(OpenGL with xcode)

這些都是錯誤的即時得到,

Undefined symbols for architecture x86_64: 
"exit(int)", referenced from: 
    myKeyboard(unsigned char, int, int) 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) 

現在,這裏是完全一樣的,我試圖編譯的代碼。

#include <OpenGL/gl.h> 
#include <OpenGL/glu.h> 
#include <OpenGL/OpenGL.h> 
#include <GLUT/glut.h> 

const int screenHeight = 480; // window height is 480 
const int screenWidth = 640 ; //window width is 640 
// <<<<<<<<<<<<<<<<<<<<<Prototypes>>>>>>>>>>>>>>>>>> 
void exit(int) ; 
// <<<<<<<<<<<<<<<<<<<<<<<myInit>>>>>>>>>>>>>>>>>>> 
void myInit(void) 
{ 
    glClearColor(1.0,1.0,1.0,0.0);  // set white background color 
    glColor3f(0.0f, 0.0f, 0.0f);   // set the drawing color 
    glPointSize(4.0);    // a ?dot? is 4 by 4 pixels 
    glLineWidth(4.0);    // a ?dot? is 4 by 4 pixels 
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    gluOrtho2D(0.0, 640.0, 0.0, 480.0); 
} 
// <<<<<<<<<<<<<<<<<<<<<<<<myDisplay>>>>>>>>>>>>>>>>> 
void myDisplay(void) 
{ 
    glClear(GL_COLOR_BUFFER_BIT);  // clear the screen 
    glBegin(GL_POINTS); 
    // glBegin(GL_LINE_STRIP) ; 
    // glBegin(GL_LINE_LOOP) ; 
    // glBegin(GL_POLYGON); 
    glVertex2i(289, 190);  // Dubhe 
    glVertex2i(320, 128) ;  // Merak 
    glVertex2i(239, 67) ;  // Phecda 
    glVertex2i(194, 101) ;  // Megrez 
    glVertex2i(129, 83) ;  // Alioth 
    glVertex2i(75, 73) ;  // Mizar 
    glVertex2i(74, 74) ;  // Alcor 
    glEnd(); 
    glFlush();   // send all output to display 
} 
// <<<<<<<<<<<<<<<<<<<<<<<<myKeyboard>>>>>>>>>>>>>> 
void myKeyboard(unsigned char theKey, int mouseX, int mouseY) 
{ 
    switch(theKey) 
    { 
     case 'Q': 
     case 'q': 
      exit(-1); //terminate the program 
     default: 
      break; // do nothing 
    } 
} 
// <<<<<<<<<<<<<<<<<<<<<<<<main>>>>>>>>>>>>>>>>>>>>>> 
int main(int argc, char** argv) 
{ 
    glutInit(&argc, argv);   // initialize the toolkit 
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); // set display mode 
    glutInitWindowSize(640, 480);  // set window size 
    glutInitWindowPosition(100, 150); // set window position on screen 
    glutCreateWindow("Big Deep - Type Q or q to quit") ; // open the screen window 
    glutDisplayFunc(myDisplay);  // register redraw function 
    glutKeyboardFunc(myKeyboard); // register the keyboard action function 
    myInit();     
    glutMainLoop();    // go into a perpetual loop 
} 

任何幫助將不勝感激!

+1

我很鬱悶,教授們仍然在這樣教OpenGL。你可能想和你的教授坐下來,提醒他們[他們不應該教Legacy OpenGL](http://gamedev.stackexchange.com/questions/34108/opengl-vbo-or-glbegin-glend),應該堅持到2008年還沒有被棄用的OpenGL函數。我引用的帖子引用了大量的話:「*有些人認爲先學習老東西比較好,因爲它更容易一點,但是你學到的東西大多是無用的,必須忘掉。*「。 – Xirema

+0

僅供參考,你得到的錯誤是鏈接錯誤的結果,特別是與你的教授使用'exit'有關。不知何故,在構建過程中的某個地方,您沒有引用正確的目標文件來鏈接到最終的可執行文件。如果我對您的特定構建環境有所瞭解,我會發布更詳細的診斷說明作爲答案。 – Xirema

+0

他想教2的理由。x是因爲「它更適合教學,它更容易建立到4.x而不是學習4,然後學習更舊的東西」,這對我也沒有任何意義。我可能是錯的,但我認爲退出功能是GLUT庫的一部分,但我不確定。這就是我所能提供的所有幫助,就像我說過的,我今天才開始嘗試使用它。謝謝您的幫助! – csm60

回答

0

您需要添加下面靠近你的源文件的頂部:

#include <stdlib.h> 

並刪除這一行:

void exit(int) ; 

首先,你應該始終使用適當的系統頭,以獲得系統庫函數的聲明。這在macOS中尤其如此,其中聲明可以具有影響函數如何鏈接的重要屬性。

但是,在這種情況下,缺乏這樣的屬性並不是真正的問題。這裏的問題是你正在構建一個C++程序。在C++中,函數的參數類型是其符號名稱的一部分。你可以在你引用的錯誤信息中看到這一點。但是exit()函數是C標準庫的一部分。它本身不是C++接口。它的符號名稱是_exit,沒有指示其參數數量或類型。

您的代碼已合併對符號的引用,該符號轉換爲exit(int),而系統庫中的實際符號僅爲_exit。他們不匹配,所以你會得到一個符號未找到的鏈接器錯誤。

當stdlib.h頭文件包含在C++翻譯單元中時,stdlib.h頭文件要特別小心地將它的函數聲明包裝在extern "C" { ... }中。因此,包含該頭文件以獲取該聲明會告訴C++編譯器不要使用C++風格的符號名稱,而要使用C風格的符號名稱。

您也可以通過在您自己的代碼中聲明exit()extern "C"「解決」該問題,但這是錯誤的方法。只需包含正確的標題。

+0

非常感謝,我改變了它,它效果很好!所以有些奇怪的是,在我知道這一點上,我們不應該包括正確的庫。所以我剛開始添加庫只是爲了看看它會如何工作,並且#include 使它工作。我想這是因爲我想自從要求'q'或'Q'終止以後,它需要一個輸入庫。 – csm60

相關問題