2011-10-02 57 views
1

下面是我在DevCpp(windows)中编写的一些代码,现在我试图让它在linux下运行,但没有取得太大的成功。 这里是源代码C++中的多重定义错误

screen.h

#ifndef SCREEN_H 
#define SCREEN_H 

#include <graphics.h> 

class Screen 
{ 
     private: 
       int max_x,max_y,grid_size; 
       int delta_x,delta_y; 
       int origin_x,origin_y; 
     public: 
     // Default Constructor to Initialize the screen with the grid 
     Screen(int xcoord=641, int ycoord=641, int grid=8) 
     { 
      //variable initialization 
      max_x = xcoord; 
      max_y = ycoord; 
      grid_size = grid; 

      delta_x = max_x/grid_size; 
      delta_y = max_y/grid_size; 

      origin_x = grid_size/2 * delta_x; 
      origin_y = grid_size/2 * delta_y; 

      //plotting the initial grid 
      int gd,gm; 
      initgraph(&gd,&gm,NULL); 
      //draw the x component of the grid 
      for(int i=0; i<max_x; i += delta_x) 
      { 
        if(i != max_x/2) 
         setcolor(GREEN); 
        else 
         setcolor(RED); 
        line(i,0,i,max_y); 
      } 
      //draw the y component of the grid 
      for(int i=0; i<max_y; i += delta_y) 
      { 
        if(i != max_y/2) 
         setcolor(GREEN); 
        else 
         setcolor(RED); 
        line(0,i,max_x,i); 
      } 
      //mark the origin with a white dot to acertain its coordinates for future use 
      putpixel(origin_x,origin_y,WHITE); 
      std::cout<<origin_x<<"\t"<<origin_y<<"\n"; 
     } 



     //Method prototypes 
     void plot_pixel(int xcoord,int ycoord,int col=WHITE) 
     { 
     int l,t,r,b; 
     l = origin_x + xcoord * delta_x; 
     r = l + delta_x; 
     b = origin_y - ycoord * delta_y; 
     t = b - delta_y; 
     setcolor(col); 
     bar(l,t,r,b); 
     setcolor(WHITE); 
    } 
}; 
#endif 

circles.cpp

#include<iostream> 
#include<cmath> 
#include "screen.h" 
using namespace std; 

void draw_midpoint_circle(Screen ob, int radius); 
void circlepointplot(Screen ob, int m, int n); 
void trigonometric_circle(Screen ob, int radius); 

int main() { 
    Screen scr = Screen(641, 641, 16); 
    int choice, rad; 
    cout << "Menu\n 1. Midpoint Circle Drawing Algorithm\n 2. Bresenham's Circle Drawing Algorithm \n 3. Trigonometric Method\n"; 
    cin>>choice; 
    cout << "Enter Radius \t"; 
    cin>>rad; 

    switch (choice) { 
     case 1: 
      draw_midpoint_circle(scr, rad); 
      break; 
     case 2: 
      draw_midpoint_circle(scr, rad); 
      break; 
     case 3: 
      trigonometric_circle(scr, rad); 
      break; 
     default: 
      cout << "Wrong Choice\n"; 
      break; 
    } 

    getch(); 
    return 0; 
} 

void trigonometric_circle(Screen ob, int radius) { 
    double angle = 0.0; 
    while (angle <= 360) { 
     int dx = 641/16; 
     int x = int(radius * cos(angle)); 
     int y = int(radius * sin(angle)); 
     angle = angle + 5; 
     ob.plot_pixel(x, y, 0); 
     cout << "Point Plotted " << x << "\t" << y << endl; 
     char buffer[50]; 
     sprintf(buffer, "%d,%d", x, y); 
     outtextxy(320 + ((x + 1) * dx), 320 - ((y - 1) * dx), buffer); 
     getch(); 
    } 
} 

void draw_midpoint_circle(Screen ob, int radius) { 
    float dp; 
    int x, y; 
    x = 0; 
    y = radius; 
    dp = 1 - radius; 
    while (x < y) { 
     circlepointplot(ob, x, y); 
     if (dp < 0) 
      dp = dp + 2 * x + 3; 
     else { 
      dp = dp + 2 * (x - y) + 5; 
      y--; 
     } 

     x++; 
     circlepointplot(ob, x, y); 
    } 
} 

void circlepointplot(Screen ob, int m, int n) { 
    ob.plot_pixel(m, n, 0); 
    ob.plot_pixel(n, m, 0); 
    ob.plot_pixel(m, -n, 0); 
    ob.plot_pixel(n, -m, 0); 
    ob.plot_pixel(-m, n, 0); 
    ob.plot_pixel(-n, m, 0); 
    ob.plot_pixel(-m, -n, 0); 
    ob.plot_pixel(-n, -m, 0); 

    cout << "Point Plotted" << m << "\t" << n << endl; 
    cout << "Point Plotted" << n << "\t" << m << endl; 
    cout << "Point Plotted" << m << "\t" << -n << endl; 
    cout << "Point Plotted" << n << "\t" << -m << endl; 
    cout << "Point Plotted" << -m << "\t" << n << endl; 
    cout << "Point Plotted" << -n << "\t" << m << endl; 
    cout << "Point Plotted" << -m << "\t" << -n << endl; 
    cout << "Point Plotted" << -n << "\t" << -m << endl; 
    int dx = 641/16; 
    char buffer[50]; 
    sprintf(buffer, "%d,%d", m, n); 
    outtextxy(320 + ((m + 1) * dx), 320 - ((n - 1) * dx), buffer); 
    getch(); 

} 

我使用graphics.h对于Linux。基本程序运行良好。 ,我得到的错误是

g++ -c screen.cpp -o screen.o 
g++ -c circles.cpp -o circles.o 
g++ screen.o circles.o -o "circle.exe" -lgraph 
circles.o:(.bss+0x0): multiple definition of `screen' 
screen.o:(.bss+0x0): first defined here 
circles.o:(.bss+0x8): multiple definition of `Font_surface' 
screen.o:(.bss+0x8): first defined here 
circles.o:(.bss+0x10): multiple definition of `_fgcolor' 
screen.o:(.bss+0x10): first defined here 
circles.o:(.bss+0x14): multiple definition of `_bgcolor' 
screen.o:(.bss+0x14): first defined here 
circles.o:(.bss+0x18): multiple definition of `_fontcolor' 
screen.o:(.bss+0x18): first defined here 
circles.o:(.bss+0x1c): multiple definition of `_pid' 
screen.o:(.bss+0x1c): first defined here 
circles.o:(.bss+0x20): multiple definition of `CP' 
screen.o:(.bss+0x20): first defined here 
circles.o:(.bss+0x40): multiple definition of `InternalFont' 
screen.o:(.bss+0x40): first defined here 
circles.o:(.bss+0x850): multiple definition of `TP' 
screen.o:(.bss+0x850): first defined here 
circles.o:(.bss+0x860): multiple definition of `_last_arc' 
screen.o:(.bss+0x860): first defined here 
circles.o:(.bss+0x878): multiple definition of `_internal_linestyle' 
screen.o:(.bss+0x878): first defined here 
circles.o:(.bss+0x888): multiple definition of `_scanlist' 
screen.o:(.bss+0x888): first defined here 
collect2: ld returned 1 exit status 

什么我做错了,我怎么得到这个工作?

将代码移动到类中后更新了错误。

/tmp/ccB2RO2Q.o: In function `main': 
circles.cpp:(.text+0x111): undefined reference to `grgetch' 
/tmp/ccB2RO2Q.o: In function `trigonometric_circle(Screen, int)': 
circles.cpp:(.text+0x242): undefined reference to `outtextxy' 
circles.cpp:(.text+0x247): undefined reference to `grgetch' 
/tmp/ccB2RO2Q.o: In function `circlepointplot(Screen, int, int)': 
circles.cpp:(.text+0x6f2): undefined reference to `outtextxy' 
circles.cpp:(.text+0x6f7): undefined reference to `grgetch' 
/tmp/ccB2RO2Q.o: In function `Screen::Screen(int, int, int)': 
circles.cpp:(.text._ZN6ScreenC2Eiii[_ZN6ScreenC5Eiii]+0xd0): undefined reference to `initgraph' 
circles.cpp:(.text._ZN6ScreenC2Eiii[_ZN6ScreenC5Eiii]+0xf7): undefined reference to `setcolor' 
circles.cpp:(.text._ZN6ScreenC2Eiii[_ZN6ScreenC5Eiii]+0x103): undefined reference to `setcolor' 
circles.cpp:(.text._ZN6ScreenC2Eiii[_ZN6ScreenC5Eiii]+0x11c): undefined reference to `line' 
circles.cpp:(.text._ZN6ScreenC2Eiii[_ZN6ScreenC5Eiii]+0x15e): undefined reference to `setcolor' 
circles.cpp:(.text._ZN6ScreenC2Eiii[_ZN6ScreenC5Eiii]+0x16a): undefined reference to `setcolor' 
circles.cpp:(.text._ZN6ScreenC2Eiii[_ZN6ScreenC5Eiii]+0x182): undefined reference to `line' 
circles.cpp:(.text._ZN6ScreenC2Eiii[_ZN6ScreenC5Eiii]+0x1b9): undefined reference to `putpixel' 
/tmp/ccB2RO2Q.o: In function `Screen::plot_pixel(int, int, int)': 
circles.cpp:(.text._ZN6Screen10plot_pixelEiii[Screen::plot_pixel(int, int, int)]+0x6d): undefined reference to `setcolor' 
circles.cpp:(.text._ZN6Screen10plot_pixelEiii[Screen::plot_pixel(int, int, int)]+0x80): undefined reference to `bar' 
circles.cpp:(.text._ZN6Screen10plot_pixelEiii[Screen::plot_pixel(int, int, int)]+0x8a): undefined reference to `setcolor' 
collect2: ld returned 1 exit status 

下面是它有一个SDL_Image *屏幕的引用文件graphics.h中

/* libgraph - TurboC graphics API on GNU/Linux 
* graphics.h: Core initialization and configuration functions 
* 
* Copyright (C) 2003 Faraz Shahbazker 
* 
* This library is free software; you can redistribute it and/or 
* modify it under the terms of the GNU Library General Public 
* License as published by the Free Software Foundation; either 
* version 2 of the License, or (at your option) any later version. 
* 
* This library is distributed in the hope that it will be useful, 
* but WITHOUT ANY WARRANTY; without even the implied warranty of 
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 
* Library General Public License for more details. 
* 
* You should have received a copy of the GNU Library General Public 
* License along with this library; if not, write to the Free 
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
* MA 02111-1307, USA 
* 
* Author: Faraz Shahbazker <[email protected]> 
*/ 

/* Graphic functions using SDL */ 

#ifndef GRAPHICS_H 
#define GRAPHICS_H 1 


#include <SDL/SDL.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <signal.h> 
#include <stdlib.h> 
#include <string.h> 
#include <time.h> 


#ifdef __cplusplus 
extern "C" 
{ 

#endif  /* __cplusplus */ 


/* graphic drivers */ 
enum _driver{DETECT=0, USER, VGA=9}; 
enum graphics_modes{VGALO=0, VGAMED, VGAHI, VGAMAX, VGA640, VGA800, VGA1024, USERMODE}; 


/* 16 colors */ 
enum _color{BLACK=0, BLUE, GREEN, CYAN, RED, MAGENTA, BROWN, LIGHTGRAY, DARKGRAY,LIGHTBLUE, LIGHTGREEN, LIGHTCYAN, LIGHTRED, LIGHTMAGENTA, YELLOW, WHITE}; 



/* global variables */ 
SDL_Surface *screen;  //main drawing screen 
SDL_Surface *Font_surface; //font screen 
Uint32 _fgcolor, _bgcolor, _fontcolor; //global color numbers 
pid_t _pid;   //Don't bother with this 



/* function prototypes */ 
void initgraph(int *graphdriver,int *graphmode,char *pathtodriver); 
void closegraph(void); 
void setgraphmode(int gmode); 
int getgraphmode(void); 
void restorecrtmode(void); 
int getmaxx(void); 
int getmaxy(void); 
void putpixel(int x, int y, int color); 
int getpixel(int, int); 
void setbkcolor(int color); 
int getbkcolor(void); 
void setcolor(int color); 
int getcolor(void); 
int getmaxcolor(void); 
char* getdrivername(void); 
char* getmodename(int mode_number); 
int getmaxmode(void); 
void detectgraph(int* graphdriver, int* graphmode); 
void getmoderange(int graphdriver, int* lomode, int* himode); 
int delay(float); 
void setfontcolor(int color); 
int getfontcolor(void); 





/*** library specific functions - not for users ***/ 
void initialize_settings (void); 
void mappixel(int, int);  //marks a pixel without updating screen 
void clippixel(int *, int *); /* Clip pixel (x,y) to current 
           screen size*/ 
void mapword(int,int,int); 
void mapvword(int,int,int); 
int colorrev(const Uint8); // maps 0..255 8-bit color to 0..15 TC color 
Uint8 colortrans(const int); // maps 0..15 TC color to 0..255 8-bit color 
void ctrlbreak(void);  // To detect user interrupt  
void inthandler(int);  // clean up on user interrupt 
void safe_update(int top, int left, int right, int bottom); 
    /* update screen within boundary */ 

#define CHECK_INITIALIZATION\ 
    if (!getenv("LIBGRAPHICS_ACTIVE")) \ 
    { \ 
     fprintf(stderr, "*** The graphics system has not been initialized!\n"); \ 
     fprintf(stderr, "*** Call initgraph() before trying to use graphics functions.\n"); \ 
     exit(-1); \ 
    } 

struct {int x;int y;}CP; 

#include "grtext.h" 
#include "shapes.h" 
#include "polygon.h" 

#ifdef __cplusplus 
} 
#endif  /* __cplusplus */ 


#endif  /* LIBGRAPH_H */ 
+1

这个问题可能在你的'graphics.h'中。顺便说一句,你可以像这样直接构建'Screen':'Screen scr(641,641,16);' –

回答

1

graphics.h中包含以下行:

 
/* global variables */ 
SDL_Surface *screen;  //main drawing screen 
SDL_Surface *Font_surface; //font screen 
Uint32 _fgcolor, _bgcolor, _fontcolor; //global color numbers 
pid_t _pid;   //Don't bother with this 

这是一个有点怪,但这种H-文件创建全局变量。这意味着,如果将此文件包含到多个.cpp文件中,则会出现多个定义错误。我不知道为什么这个h文件是这样写的,只有在graphics.h只包含在一个cpp文件中时,程序才会被链接。如果您可以更改此文件,请在每个全局变量前添加extern关键字,并在某些.cpp文件中创建这些变量(如有必要)。

+0

但在我的代码中,我只将它包含在Screen.h文件中,而没有其他地方。我对C++不太了解,完全理解了这个外部部分,如果能够详细阐述,那将会很棒。 – nikhil

+0

其中一个cpp文件是实现文件, 我可以将代码移动到头文件中以使其内联。 – nikhil

+0

尝试这样做只是为了看看会发生什么。 –

1

你的第一个错误消息是

circles.o :(。BSS +为0x0) :`屏幕'的多重定义

在你的代码中,当我写这个时,没有什么叫“屏幕”。

因此,问题似乎已经解决了。


编辑:现在你已经添加了(别人的)graphics.h,笔者对以下的无知是导致问题的原因内容:

C++ 98§ 7.5/7
链接说明的包含支撑封闭声明-SEQ并 不会影响瓦特的形式包含的声明是否定义(3.1)。

因此,指针变量声明中有定义。

遗憾的是,似乎不仅是标题的作者,也目前的C++标准听错了:直接
的声明:

C++ 11第7.5节/ 7包含在链接规范中被视为包含 extern说明符(7.1。1)为了确定声明的名称的联系以及它是否是一个定义。

根据该标准化文本这是因为如果每个指针变量声明为 extern并且因此将 只有一个声明(不是定义)。但是,即使在C++ 11中,非规范示例 也显示了它的意图,即它是一个定义。

所有这一切说,这也是我的新闻,我是一个老手。这似乎只是 标准中的一个毫无意义的怪癖,一个不必要的陷阱。但可能是因为在C++ 中,没有其他方式可以为对象表达纯声明与定义。 。

干杯&心连心,

+1

对不起,我不明白你的意思。 你的意思是说,而不是我的代码存在问题,图书馆本身有什么问题吗? 如果是这样,我该如何解决它? – nikhil

+2

@nikhil:我在说你正在展示的代码,因为我正在写这篇文章,而不是展示问题的代码。你的问题是你的马自达汽车。你向我们展示你的沃尔沃图片。 –

+0

+1引导我走向正确的方向。 – nikhil