2011-10-02 5 views
1

Voici un code que j'ai écrit dans DevCpp (windows), maintenant j'essaie de le faire fonctionner sous Linux sans beaucoup de succès. Voici le code sourceErreurs de définition multiple en C++

de 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(); 

} 

J'utilise graphics.h pour linux. Les programmes de base fonctionnent bien. Les erreurs que je reçois sont

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 

Qu'est-ce que je fais mal, comment puis-je obtenir ce travail?

Erreurs mises à jour après avoir déplacé le code dans la classe.

/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 

Voici le fichier graphics.h il a une référence à un SDL_image * écran

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

Le problème peut être dans votre 'graphics.h'. En passant, vous pouvez construire 'Screen' directement comme ceci:' Screen scr (641,641,16); ' –

Répondre

1

graphics.h contient les lignes suivantes:

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

C'est un peu étrange, mais ce fichier crée h variables globales. Cela signifie que si vous incluez ce fichier dans plusieurs fichiers .cpp, vous avez plusieurs erreurs de définition. Je ne sais pas pourquoi ce fichier h est écrit de cette façon, le programme ne sera lié que si graphics.h est inclus dans un seul fichier cpp. Si vous pouvez modifier ce fichier, ajoutez un mot-clé extern avant chaque variable globale et créez ces variables (si nécessaire) dans un fichier .cpp.

+0

mais dans mon code, je l'inclue uniquement dans le fichier Screen.h et nulle part ailleurs. Je ne suis pas très bon avec C++ pour comprendre complètement la partie externe, ce serait génial si vous pouviez élaborer. – nikhil

+0

l'un des fichiers cpp est le fichier d'implémentation, Je pourrais déplacer le code dans le fichier d'en-tête pour le rendre en ligne. – nikhil

+0

Essayez de le faire juste pour voir ce qui se passe. –

1

Votre premier message d'erreur est

circles.o :(. Bss + 0x0) : définition multiple de `screen '

Dans votre code, comme j'écris ceci, il n'y a rien appelé" écran ".

Par conséquent, le problème semble déjà résolu.


EDIT: maintenant que vous avez ajouté le contenu de (quelqu'un d'autre) graphics.h, l'ignorance de l'auteur de ce qui suit est la cause du problème:

C++ 98 § 7.5/7
La forme de la spécification de liaison qui contient une embase clos déclaration-seq ne pas affecté w Les déclarations contenues sont des définitions ou non (3.1).

Ainsi, les déclarations de variable de pointeur sont des définitions.

Malheureusement, il semble que non seulement l'auteur de cet en-tête, mais aussi la norme actuelle C++ se sont trompés:

C++ 11 §7.5/7:
Une déclaration directement contenu dans une spécification de liaison est traité comme s'il contient le spécificateur extern (7.1.1) dans le but de déterminer le lien du nom déclaré et s'il s'agit d'une définition.

Selon ce texte normatif, il est comme si chaque variable pointeur a été déclarée comme extern et serait donc seulement une déclaration (non une définition). Cependant, même en C++ 11, l'exemple non normatif montre l'intention, qu'il s'agit d'une définition. Tout ce qui a été dit, c'était aussi une nouvelle pour moi, et je suis un vieux bonhomme à ce sujet. Il semble être juste une bizarrerie sans signification dans la norme, un gotcha inutile. Mais c'est peut-être parce qu'en C++ il n'y a pas d'autre moyen d'exprimer la déclaration pure par rapport à la définition d'un objet. .

Vive & HTH,

+1

Je suis désolé de ne pas comprendre ce que vous voulez dire par là. Voulez-vous dire qu'au lieu d'avoir un problème avec mon code, il y a quelque chose qui ne va pas dans la bibliothèque elle-même? Si oui, comment dois-je procéder pour le réparer? – nikhil

+2

@nikhil: Je dis que le code que vous montrez, comme j'écris ceci, n'est pas le code exposant le problème. votre problème est avec votre voiture Mazda. vous nous montrez une image de votre volvo. –

+0

+1 pour me conduire dans la bonne direction. – nikhil

Questions connexes