我用 VC 6.0 打开配书光盘中的一个例子,可以编译成功,可是我自己新建一个工程,把光盘中的程序拷贝到这个工程,
编译时提示这样的错误:
--------------------Configuration: DirectDrawMoving - Win32 Debug--------------------
Compiling...
GameMain.cpp
MyDirectDraw.cpp
WinMain.cpp
Linking...
WinMain.obj : error LNK2005: "struct tobject  tankobject" (?tankobject@@3Utobject@@A) already defined in GameMain.obj
Debug/DirectDrawMoving.exe : fatal error LNK1169: one or more multiply defined symbols found
Error executing link.exe.DirectDrawMoving.exe - 2 error(s), 0 warning(s)
各位大哥,这是什么原因,是不是我的 VC 环境没有设置好,
我检查了一下,和我打开光盘的一样啊?
我是错在哪里呢?
谢谢!

解决方案 »

  1.   

    WinMain.cpp 文件
    //******************
    #include <windows.h>   // include important windows stuff
    #include <windowsx.h> 
    #include <mmsystem.h>
    #include <iostream.h> // include important C/C++ stuff
    #include <conio.h>
    #include <stdlib.h>
    #include <malloc.h>
    #include <memory.h>
    #include <string.h>
    #include <stdarg.h>
    #include <stdio.h> 
    #include <math.h>
    #include <io.h>
    #include <fcntl.h>#include"../H/GameMain.h"// 全局变量
    HWND      main_window_handle = NULL; //主窗口全局变量
    HINSTANCE main_instance      = NULL; //句柄全局变量
    char buffer[80];                     //临时文本数组LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,
       LPSTR lpCmdLine,int nCmdShow)
    {
    static TCHAR szAppName[]=TEXT("");
    static TCHAR szClassName[]=TEXT("MainWinClass");
    HWND hwnd;
    MSG msg;
    WNDCLASS wndclass;
    wndclass.style = CS_DBLCLKS | CS_OWNDC | 
    CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc = WndProc;
    wndclass.cbClsExtra = 0;
    wndclass.cbWndExtra = 0;
    wndclass.hInstance = hInstance;
    wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION);
    wndclass.hCursor = LoadCursor(NULL,IDC_ARROW);
    wndclass.hbrBackground =  (HBRUSH)GetStockObject(BLACK_BRUSH);
    wndclass.lpszMenuName = NULL;
    wndclass.lpszClassName = szClassName; //设置句柄全局变量
    main_instance = hInstance;

    if(!RegisterClass(&wndclass))
    {
    MessageBox(NULL,TEXT("This program requires Windows NT !"),
    szAppName,MB_ICONERROR);
    return 0;
    } hwnd = CreateWindow(szClassName,
    TEXT(""),
    WS_POPUP | WS_VISIBLE,
    0,
    0,
    320,
    240,
    NULL,
    NULL,
    hInstance,
    NULL );
    ShowWindow(hwnd,nCmdShow);
    UpdateWindow(hwnd); //设置主窗口全局变量
    main_window_handle = hwnd;

    //游戏初始化
    GameInit();    //主循环
    while(TRUE)
    {
    //检测消息
    if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))

    //是否退出程序
    if (msg.message == WM_QUIT)
    break;

    //消息转换
    TranslateMessage(&msg);
    DispatchMessage(&msg);
    }
        
    //游戏循环
    GameMain();
    }  //游戏退出控制
    GameShut(); return msg.wParam;
    }
    LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,
     LPARAM lParam)
    {
    HDC hdc;
    PAINTSTRUCT ps; switch(message)
    {
    case WM_CREATE:
    return 0;
    case WM_PAINT:
    hdc=BeginPaint(hwnd,&ps);
    EndPaint(hwnd,&ps);
    return 0;

    //获取键盘输入
    case WM_KEYDOWN:
    switch(wParam)
    {
    //按Esc键推出
    case VK_ESCAPE:
    PostQuitMessage(0);
    return 0;
    } case WM_DESTROY:
    PostQuitMessage(0);
    return 0;
    } return DefWindowProc(hwnd,message,wParam,lParam);
    }//******************************************
    GameMain.h 文件
    //*********************************************8
    //函数
    int GameMain(void);  //游戏循环
    int GameInit(void);  //游戏初始化
    int GameShut(void);  //游戏退出控制
    struct tobject
    {
    int tankid;
    int life;
    int x;
    int y;
    int speed;
    struct tobject *next;
    }tankobject;
    //移动坦克
    int TankMoving(void);//************************************************
      

  2.   

    GameMain.cpp  文件
    //**************************************************************8#include <windows.h>   // include important windows stuff
    #include <windowsx.h> 
    #include <mmsystem.h>
    #include <iostream.h> // include important C/C++ stuff
    #include <conio.h>
    #include <stdlib.h>
    #include <malloc.h>
    #include <memory.h>
    #include <string.h>
    #include <stdarg.h>
    #include <stdio.h> 
    #include <math.h>
    #include <io.h>
    #include <fcntl.h>#include "../H/GameMain.h"
    #include "../H/MyDirectDraw.h"//键盘定义
    #define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
    #define KEYUP(vk_code)   ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)extern HWND main_window_handle; //外部定义的主窗口变量
    extern HINSTANCE main_instance; //外部定义的主句柄
    extern char buffer[80];         //外部定义的临时数组RECT Dest,Src;//初始坦克序列
    struct tobject *movetanktop,*movetank,*movetanktemp;//////////////////////////////////
    //游戏循环
    //////////////////////////////////
    int GameMain(void)
    {
    //遇Esc键退出
    if (KEYDOWN(VK_ESCAPE))
    SendMessage(main_window_handle,WM_CLOSE,0,0); //清屏
    memset(&ddbltfx,0,sizeof(ddbltfx));
    ddbltfx.dwSize=sizeof(ddbltfx);
    ddbltfx.dwFillColor = _RGB16BIT565(0,0,0); if (FAILED(lpDDback->Blt(NULL, NULL, NULL, 
    DDBLT_COLORFILL | DDBLT_WAIT,&ddbltfx))) 
    {
    MessageBox(NULL,TEXT("Back surface fill color error!"),
    TEXT("Wrong!"),MB_OK);
    return(1);
    } //将备用画面背景部分拷贝到后备画面
    SurfaceToBack(lpDDbpic,0,0,799,599,lpDDback,0,0,799,599);
    TankMoving();

    //锁住后备画面
    memset(&ddsd,0,sizeof(ddsd));
    ddsd.dwSize=sizeof(ddsd);
    if (FAILED(lpDDback->Lock(NULL,&ddsd,
    DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR,
    NULL)))
    {
    MessageBox(NULL,TEXT("primary surface lock error!"),
    TEXT("Wrong!"),MB_OK);
    return(1);
    }
    //解锁后备画面
    if (FAILED(lpDDback->Unlock(NULL)))
    {
    MessageBox(NULL,TEXT("primary surface unlock error!"),
    TEXT("Wrong!"),MB_OK);
    return(1);
    } //翻页
    while (FAILED(lpDDprimary->Flip(NULL, DDFLIP_WAIT))); return 0;
    }
    //////////////////////////////////
    //游戏初始化
    //////////////////////////////////
    int GameInit(void)
    {

    //DirectDraw初始化
    MyDirectDrawInit(); //剪切序列
    RECT rect_list[1] = {{0,0,799,599}}; //建立剪切区
    if (FAILED(lpDDclip = CreatDDClipper(lpDDback,1,rect_list)))
    {
    MessageBox(NULL,TEXT("primary surface Blt error!"),
    TEXT("Wrong!"),MB_OK);
    return(0);
    } //游戏背景初始化
    if(!(lpDDbpic  = CreatePicSurface("Pic/BackGround1.bmp" , 0 , 0)))
    {
    MessageBox(NULL,TEXT("Create Pic Background Surface error!"),
    TEXT("Wrong!"),MB_OK);
    return(1);
    } //坦克序列初始化
    movetank = (struct tobject * )malloc(sizeof(tankobject));
    movetank->tankid = rand()%12;
    movetank->life = 1;
    movetank->x = 800+rand()%4800;
    movetank->y = rand()%550;
    movetank->speed = rand()%6;
    movetank->next = NULL;
    movetanktop = movetank;
    for(int tanki = 2; tanki < 100 ; tanki++)
    {
    movetanktemp = (struct tobject *)malloc(sizeof(tankobject));
    movetanktemp->tankid = rand()%12;
    movetanktemp->x = 800+rand()%4800;
    movetanktemp->y = rand()%550;
    movetanktemp->life = 1;
    movetanktemp->speed = 3+rand()%4;
    movetanktemp->next = NULL; movetank->next = movetanktemp;
    movetank = movetank->next;
    }

    return 0;
    }//////////////////////////////////
    //游戏结束
    //////////////////////////////////
    int GameShut(void)
    {
    //DirectDraw结束
    MyDirectDrawShut(); return 0;
    }//////////////////////////////////
    //移动坦克
    //////////////////////////////////
    int TankMoving(void)
    { movetanktemp = movetanktop;
    for(movetanktemp = movetanktop ; movetanktemp != NULL ; movetanktemp = movetanktemp->next)
    {
    if( movetanktemp->life == 0)
    continue; if( movetanktemp->x <= -50)
    {
    movetanktemp->life = 0 ;
    continue;
    } movetanktemp->x = movetanktemp->x - movetanktemp->speed; if( movetanktemp->x >= 799)
    continue; switch(movetanktemp->tankid)
    {
    case 0:
    SurfaceToBack(lpDDbpic,0,600,50,650,lpDDback,
    movetanktemp->x , movetanktemp->y ,
    movetanktemp->x+50 ,movetanktemp->y+50);
    break;
    case 1: 
    SurfaceToBack(lpDDbpic,0,600,50,650,lpDDback,
    movetanktemp->x , movetanktemp->y ,
    movetanktemp->x+50 ,movetanktemp->y+50);
    break;
    case 2: 
    SurfaceToBack(lpDDbpic,50,600,100,650,lpDDback,
    movetanktemp->x , movetanktemp->y ,
    movetanktemp->x+50 ,movetanktemp->y+50);
    break;
    case 3: 
    SurfaceToBack(lpDDbpic,100,600,150,650,lpDDback,
    movetanktemp->x , movetanktemp->y ,
    movetanktemp->x+50 ,movetanktemp->y+50);
    break;
    case 4: 
    SurfaceToBack(lpDDbpic,150,600,200,650,lpDDback,
    movetanktemp->x , movetanktemp->y ,
    movetanktemp->x+50 ,movetanktemp->y+50);
    break;
    case 5: 
    SurfaceToBack(lpDDbpic,200,600,250,650,lpDDback,
    movetanktemp->x , movetanktemp->y ,
    movetanktemp->x+50 ,movetanktemp->y+50);
    break;
    case 6: 
    SurfaceToBack(lpDDbpic,250,600,300,650,lpDDback,
    movetanktemp->x , movetanktemp->y ,
    movetanktemp->x+50 ,movetanktemp->y+50);
    break;
    case 7: 
    SurfaceToBack(lpDDbpic,0,650,50,700,lpDDback,
    movetanktemp->x , movetanktemp->y ,
    movetanktemp->x+50 ,movetanktemp->y+50);
    break;
    case 8: 
    SurfaceToBack(lpDDbpic,50,650,100,700,lpDDback,
    movetanktemp->x , movetanktemp->y ,
    movetanktemp->x+50 ,movetanktemp->y+50);
    break;
    case 9: 
    SurfaceToBack(lpDDbpic,100,650,150,700,lpDDback,
    movetanktemp->x , movetanktemp->y ,
    movetanktemp->x+50 ,movetanktemp->y+50);
    break;
    case 10: 
    SurfaceToBack(lpDDbpic,150,650,200,700,lpDDback,
    movetanktemp->x , movetanktemp->y ,
    movetanktemp->x+50 ,movetanktemp->y+50);
    break;
    case 11: 
    SurfaceToBack(lpDDbpic,200,650,250,700,lpDDback,
    movetanktemp->x , movetanktemp->y ,
    movetanktemp->x+50 ,movetanktemp->y+50);
    break;
    case 12: 
    SurfaceToBack(lpDDbpic,250,650,300,700,lpDDback,
    movetanktemp->x , movetanktemp->y ,
    movetanktemp->x+50 ,movetanktemp->y+50);
    break;
    } } return 0;
    }