在下近日研究一个DX程序,虽然在工程里加入了ddraw.lib的处理并#include "ddraw.h",也安装了dx8.1,link时仍然出现:
"LIBCD.lib(crt0.obj) : error LNK2001: unresolved external symbol _main
Debug/demo7_1.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe."究竟是为何???令小的n思不得其解(n->999)
源程如下(copy后即可通过编译,link通不过),分?我分给你,绝不留一分!!!(誓言)// DEMO7_1.CPP basic full-screen 16-bit color pixel plotting DirectDraw demo// INCLUDES ///////////////////////////////////////////////#define WIN32_LEAN_AND_MEAN  // just say no to MFC#define INITGUID#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 <ddraw.h> // include directdraw
 
#define WINDOW_CLASS_NAME "WINCLASS1"
#define SCREEN_WIDTH    640  // size of screen
#define SCREEN_HEIGHT   480
#define SCREEN_BPP      16    // bits per pixel
typedef unsigned short USHORT;
typedef unsigned short WORD;
typedef unsigned char  UCHAR;
typedef unsigned char  BYTE;
#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEYUP(vk_code)   ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)// this builds a 16 bit color value in 5.5.5 format (1-bit alpha mode)
#define _RGB16BIT555(r,g,b) ((b%32) + ((g%32) << 5) + ((r%32) << 10))// this builds a 16 bit color value in 5.6.5 format (green dominate mode)
#define _RGB16BIT565(r,g,b) ((b%32) + ((g%64) << 6) + ((r%32) << 11))// initializes a direct draw struct
#define DDRAW_INIT_STRUCT(ddstruct) { memset(&ddstruct,0,sizeof(ddstruct)); ddstruct.dwSize=sizeof(ddstruct); }// GLOBALS ////////////////////////////////////////////////
HWND      main_window_handle = NULL; // globally track main window
HINSTANCE hinstance_app      = NULL; // globally track hinstance// directdraw stuffLPDIRECTDRAW          lpdd         = NULL;   // dd object
LPDIRECTDRAW4         lpdd4        = NULL;   // dd4 object
LPDIRECTDRAWSURFACE4  lpddsprimary = NULL;   // dd primary surface
LPDIRECTDRAWSURFACE4  lpddsback    = NULL;   // dd back surface
LPDIRECTDRAWPALETTE   lpddpal      = NULL;   // a pointer to the created dd palette
LPDIRECTDRAWCLIPPER   lpddclipper  = NULL;   // dd clipper
PALETTEENTRY          palette[256];          // color palette
PALETTEENTRY          save_palette[256];     // used to save palettes
DDSURFACEDESC2        ddsd;                  // a direct draw surface description struct
DDBLTFX               ddbltfx;               // used to fill
DDSCAPS2              ddscaps;               // a direct draw surface capabilities struct
HRESULT               ddrval;                // result back from dd calls
DWORD                 start_clock_count = 0; // used for timingchar buffer[80];                     // general printing buffer// FUNCTIONS //////////////////////////////////////////////LRESULT CALLBACK WindowProc(HWND hwnd, 
    UINT msg, 
                            WPARAM wparam, 
                            LPARAM lparam)
{
// this is the main message handler of the system
PAINTSTRUCT ps; // used in WM_PAINT
HDC hdc; // handle to a device context
char buffer[80];        // used to print strings// what is the message 
switch(msg)
{
case WM_CREATE: 
        {
// do initialization stuff here
        // return success
return(0);
} break;
   
case WM_PAINT: 
{
// simply validate the window 
        hdc = BeginPaint(hwnd,&ps);  
        
        // end painting
        EndPaint(hwnd,&ps);        // return success
return(0);
    } break; case WM_DESTROY: 
{ // kill the application, this sends a WM_QUIT message 
PostQuitMessage(0);        // return success
return(0);
} break; default:break;    } // end switch// process any messages that we didn't take care of 
return (DefWindowProc(hwnd, msg, wparam, lparam));} // end WinProc///////////////////////////////////////////////////////////inline void Plot_Pixel_Faster16(int x, int y, 
                                int red, int green, int blue, 
                                USHORT *video_buffer, int lpitch16)
{
// this function plots a pixel in 16-bit color mode
// assuming that the caller already locked the surface
// and is sending a pointer and byte pitch to it// first build up color WORD
USHORT pixel = _RGB16BIT565(red,green,blue);// write the data
video_buffer[x + y*lpitch16] = pixel;} // end Plot_Pixel_Faster16////////////////////////////////////////////////////////////

解决方案 »

  1.   

    另一部分(需加入前部分):
    int Game_Main(void *parms = NULL, int num_parms = 0)
    {
    // this is the main loop of the game, do all your processing
    // here// for now test if user is hitting ESC and send WM_CLOSE
    if (KEYDOWN(VK_ESCAPE))
       SendMessage(main_window_handle,WM_CLOSE,0,0);
    // plot 1000 random pixels to the primary surface and return
    // clear ddsd and set size, never assume it's clean
    DDRAW_INIT_STRUCT(ddsd); // lock the primary surface
    if (FAILED(lpddsprimary->Lock(NULL, &ddsd,
                       DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,
                       NULL)))
       return(0);// now ddsd.lPitch is valid and so is ddsd.lpSurface// make a couple aliases to make code cleaner, so we don't
    // have to cast
    int lpitch16 = (int)(ddsd.lPitch >> 1);
    USHORT *video_buffer = (USHORT *)ddsd.lpSurface;// plot 1000 random pixels with random colors on the
    // primary surface, they will be instantly visible
    for (int index=0; index < 1000; index++)
        {
        // select random position and color for 640x480x16
        int red   = rand()%256;
        int green = rand()%256;
        int blue  = rand()%256;
        int x = rand()%640;
        int y = rand()%480;    // plot the pixel
        Plot_Pixel_Faster16(x,y,red,green,blue,video_buffer,lpitch16);           } // end for index
    // now unlock the primary surface
    if (FAILED(lpddsprimary->Unlock(NULL)))
       return(0);// return success or failure or your own return code here
    return(1);} // end Game_Main////////////////////////////////////////////////////////////int Game_Init(void *parms = NULL, int num_parms = 0)
    {
    // this is called once after the initial window is created and
    // before the main event loop is entered, do all your initialization
    // here// first create base IDirectDraw interface
    if (FAILED(DirectDrawCreate(NULL, &lpdd, NULL)))
       return(0);// now query for IDirectDraw4
    if (FAILED(lpdd->QueryInterface(IID_IDirectDraw4,
                                   (LPVOID *)&lpdd4)))
       return(0);// set cooperation to full screen
    if (FAILED(lpdd4->SetCooperativeLevel(main_window_handle, 
                                          DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX | 
                                          DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT)))
       return(0);// set display mode to 640x480x16
    if (FAILED(lpdd4->SetDisplayMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP,0,0)))
       return(0);// clear ddsd and set size
    memset(&ddsd,0,sizeof(ddsd)); 
    ddsd.dwSize = sizeof(ddsd);// enable valid fields
    ddsd.dwFlags = DDSD_CAPS;// request primary surface
    ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;// create the primary surface
    if (FAILED(lpdd4->CreateSurface(&ddsd, &lpddsprimary, NULL)))
       return(0);// return success or failure or your own return code here
    return(1);} // end Game_Init/////////////////////////////////////////////////////////////int Game_Shutdown(void *parms = NULL, int num_parms = 0)
    {
    // this is called after the game is exited and the main event
    // loop while is exited, do all you cleanup and shutdown here// now the primary surface
    if (lpddsprimary)
       {
       lpddsprimary->Release();
       lpddsprimary = NULL;
       } // end if// now blow away the IDirectDraw4 interface
    if (lpdd4)
       {
       lpdd4->Release();
       lpdd4 = NULL;
       } // end if// return success or failure or your own return code here
    return(1);} // end Game_Shutdown
      

  2.   

    以下是最后一部分,三者合一,即可通过COMPILE,但BUILD通不过,即便ddraw.lib,ddraw.h均到位,同样通不过!// WINMAIN ////////////////////////////////////////////////int WINAPI WinMain( HINSTANCE hinstance,
    HINSTANCE hprevinstance,
    LPSTR lpcmdline,
    int ncmdshow)
    {WNDCLASSEX winclass; // this will hold the class we create
    HWND    hwnd;  // generic window handle
    MSG    msg;  // generic message
    HDC        hdc;      // graphics device context// first fill in the window class stucture
    winclass.cbSize         = sizeof(WNDCLASSEX);
    winclass.style = CS_DBLCLKS | CS_OWNDC | 
                              CS_HREDRAW | CS_VREDRAW;
    winclass.lpfnWndProc = WindowProc;
    winclass.cbClsExtra = 0;
    winclass.cbWndExtra = 0;
    winclass.hInstance = hinstance;
    winclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    winclass.hCursor = LoadCursor(NULL, IDC_ARROW); 
    winclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
    winclass.lpszMenuName = NULL;
    winclass.lpszClassName = WINDOW_CLASS_NAME;
    winclass.hIconSm        = LoadIcon(NULL, IDI_APPLICATION);// save hinstance in global
    hinstance_app = hinstance;// register the window class
    if (!RegisterClassEx(&winclass))
    return(0);// create the window
    if (!(hwnd = CreateWindowEx(NULL,                  // extended style
                                WINDOW_CLASS_NAME,     // class
        "DirectDraw 16-Bit Full-Screen Demo", // title
        WS_POPUP | WS_VISIBLE,
          0,0,   // initial x,y
        SCREEN_WIDTH,SCREEN_HEIGHT,  // initial width, height
        NULL,   // handle to parent 
        NULL,   // handle to menu
        hinstance,// instance of this application
        NULL))) // extra creation parms
    return(0);// save main window handle
    main_window_handle = hwnd;// initialize game here
    Game_Init();// enter main event loop
    while(TRUE)
    {
        // test if there is a message in queue, if so get it
    if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
       { 
       // test if this is a quit
           if (msg.message == WM_QUIT)
               break;

       // translate any accelerator keys
       TranslateMessage(&msg);    // send the message to the window proc
       DispatchMessage(&msg);
       } // end if
        
           // main game processing goes here
           Game_Main();
           
    } // end while// closedown game here
    Game_Shutdown();// return to Windows like this
    return(msg.wParam);} // end WinMain///////////////////////////////////////////////////////////
      

  3.   

    你的程序也太长了,而且你把问题也指偏了。不是ddraw的问题,问题是,你在vc中,默认建立的一个项目,对link使用的是默认的选项,其中指明这是一个console项目,link肯定错。
    在project->project settings->c/c++页,project options中去掉/D "console"
    在project->project settings->link页,project options中去掉
    /subsystem:console
    程序可以成功,我已经试过了。
    注意在Release编译时,要做同样的修改。
    记着给分喲,我干了足足有20分钟
      

  4.   

    就是CaptainIII说的那样,可惜我来晚了。
    你也可以用VC向导生成一个Windows应用,然后把你的代码复制进去。