0

このプログラムを C++ MSVS2010 でコンパイルしようとしていますが、次のような奇妙なコンパイラ エラーが発生します。

 Error  12  error LNK1120: 1 unresolved externals   C:\Users\win7vm\Documents\Visual Studio 2010\Projects\WinDemo \Debug\WinDemo.exe    1.

そして私も得ています

 Error  11  error LNK2019: unresolved external symbol "public: int __thiscall Dice::returnRoll(void)" (?returnRoll@Dice@@QAEHXZ) referenced in function "public: void __thiscall Dice::drawSpots(struct HDC__ *,int,int,int,int,int,int,int)" (?drawSpots@Dice@@QAEXPAUHDC__@@HHHHHHH@Z)    C:\Users\win7vm\Documents\Visual Studio 2010\Projects\WinDemo \WinDemo \Debug\WinDemo.exe   1\Dice.obj

どちらも構文に関連していないようで、完全には理解していません。基本的には、switch ステートメントを取得して、他の関数からその関数に渡された値を表示するという考え方です。私が完全に見逃しているのは、単純な参照/ポインターの問題であるとほぼ確信しています。このクラスのヘッダー、windows.h (すぐに使用できる未変更なので、必要に応じて調べることができます)、およびメイン ファイルを含む関数 (ここに関数とクラスが含まれています) があります。ほぼ確実に出てくる 2 つの質問に事前に答えさせてください。a) はい、c++ で windows.h ファイルを絶対に使用する必要があります。b) はい、この問題に使用できるより優れたライブラリと言語が 100 あることは承知しています。ここで選択の余地はありません。誰かが宣言されたグローバル変数を指摘しようとするかもしれません。グローバルは、比較的短いコード ブロックをトラブルシューティングする際に、一時的ではありますが必要な不都合でした。あなたの多くが C++ に非常に熟練していることは承知していますが、私の低レベルの C++ プログラミングを念頭に置いて、あなたの答えを説明するために忍耐を求めています。ありがとうございました。:)

** //ヘッダーファイル

#include <windows.h>
#include <math.h>
#include <vector>
using namespace std;

int count=0;
int *result = &count;

class Dice
{
public:
    void drawSpots(HDC hdc, int x1,int y1, int x2,int y2, int r, int g,int b);
    int roll();
    wchar_t * drawString();
    int returnRoll();
private:
    int x1,x2,y1,y2,sr,sg,sb;
    //int &count;
    //int *result;
    int value;
    int spotColor;
};


//definitions file


void Dice::drawSpots(HDC hdc, int x1,int y1, int x2,int y2, int r, int g,int b)
{
    *result = roll();
    //vectorOfDice.push_back(result);
    //wchar_t * drawString();
    returnRoll();
    HBRUSH hBrush = CreateSolidBrush(RGB(r,g,b));
    SelectObject(hdc,hBrush);
    switch(*result)
    {
    case 1:
        //draw something based on case
        break;
    case 2:
        //draw something based on case
        break;
    case 3:
        //draw something based on case
        break;
    case 4:
        //draw something based on case
        break;
    case 5:
        //draw something based on case      
                    break;
    case 6:
        //draw something based on case      
                    break;
    }

    DeleteObject(hBrush);
}

int Dice::roll()
{
    value=1+(rand()%6);
    return value;
}


int Dice::returnRoll()
{
    count=0;
    if((*result == 2)||(*result == 4)||(*result == 6))
    {
        count++;
    }
    return count;
}

wchar_t * Dice::drawString()
{
    //result = returnRoll(result);
    //result = roll();
    switch(*result)
    {
    case 0:
        return L"no";
        break;
    case 1:
        return L"1";
        break;
    case 2:
        return L"2";
        break;
    case 3:
        return L"3";
        break;
    case 4:
        return L"4";
        break;
    case 5:
        return L"5";
        break;
    case 6:
        return L"6";
        break;
    }
    return L"X";
}


//main file


#include <windows.h>
#include <math.h>
#include "Dice.h"


const wchar_t g_szClassName[] = L"myWindowClass";



// Step 4: the Window Procedure
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    Dice dice;

    //state variables
    static int red = 0;
    static int green = 0;
    static int blue = 100;

    static int tr = 0;
    static int tg = 0;
    static int tb = 0;

    HDC hDC;
    PAINTSTRUCT Ps;
    HPEN hPen1;
    HPEN hPen2;


    HBRUSH hBrush1;
    HFONT hFont1;
    RECT rect;
    int fontHeight = 100;


    switch(msg)
    {
        case WM_PAINT:
            hDC = BeginPaint(hwnd,&Ps);

            hPen1=CreatePen(PS_SOLID,5,RGB(red,green,blue));
            hPen2=CreatePen(PS_SOLID,5,RGB(0,0,0));

            hBrush1= CreateSolidBrush(RGB(0,0,255));

            SelectObject(hDC,hPen1);
            SelectObject(hDC,hBrush1);

            fontHeight=50;
            hFont1=CreateFont(fontHeight,0,0,0,0,1,0,0,0,0,0,0,0,L"Times New Roman");
            //hFont1=CreateFont(fontHeight,0,0,0,0,0,0,0,0,0,0,0,0,L"Arial");
            SelectObject(hDC,hFont1);

            rect.top=100;
            rect.bottom=700;
            rect.left = 550;
            rect.right =950;

            DrawText(hDC,L"There are ",-1,&rect,DT_CENTER | DT_WORDBREAK );
            rect.top=200;
            DrawText(hDC,dice.drawString(),-1,&rect,DT_CENTER | DT_WORDBREAK );
            rect.top=300;
            DrawText(hDC,L" even dice!",-1,&rect,DT_CENTER | DT_WORDBREAK );


            DeleteObject(hBrush1);
            DeleteObject(hPen2);
            DeleteObject(hPen1);
            EndPaint(hwnd,&Ps);
        break;
        case WM_KEYDOWN:
            if(wParam==VK_SPACE)
            {
                dice.roll();
                InvalidateRect(hwnd,NULL,true);
            }
            break;
        case WM_CHAR:
            if(wParam=='c')
            {
                tr=rand()%256;
                tg=rand()%256;
                tb=rand()%256;
                dice.spotColors();
            }
            InvalidateRect(hwnd,NULL,true);
            break;
        case WM_CLOSE:
            DestroyWindow(hwnd);
        break;
        case WM_DESTROY:
            PostQuitMessage(0);
        break;
        default:
            return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPSTR lpCmdLine, int nCmdShow)
{
    WNDCLASSEX wc;
    HWND hwnd;
    MSG Msg;

    //Step 1: Registering the Window Class
    wc.cbSize        = sizeof(WNDCLASSEX);
    wc.style         = 0;
    wc.lpfnWndProc   = WndProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hInstance;
    wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = g_szClassName;
    wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

    if(!RegisterClassEx(&wc))
    {
        MessageBox(NULL, L"Window Registration Failed!", L"Error!",
            MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    // Step 2: Creating the Window
    hwnd = CreateWindowEx(
        WS_EX_CLIENTEDGE,
        g_szClassName,
        L"window",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, 1000, 800,
        NULL, NULL, hInstance, NULL);

    if(hwnd == NULL)
    {
        MessageBox(NULL, L"Window Creation Failed!", L"Error!",
            MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    // Step 3: The Message Loop
    while(GetMessage(&Msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }
    return Msg.wParam;
}

**

編集: はい、ありがとう、リンカー エラーが発生していますが、Dice:: を署名に追加しました (コンパイラの不満は減ったようですが) それでも、同様の異常なエラーが発生します --

Error   11  error LNK1169: one or more multiply defined symbols found   C:\Users\win7vm\Documents\Visual Studio 2010\Projects\\WinDemo \Debug\WinDemo.exe   1

Error   10  error LNK2005: "int * result" (?result@@3PAHA) already defined in Dice.obj  C:\Users\win7vm\Documents\Visual Studio 2010\Projects\WinDemo \WinDemo \main.obj

Error   9   error LNK2005: "int count" (?count@@3HA) already defined in Dice.obj    C:\Users\win7vm\Documents\Visual Studio 2010\Projects\WinDemo \WinDemo \main.obj
4

4 に答える 4

8

定義Dice::の署名を入れていません。returnRollこれにより、リンカーは必要なときにそれを見つけられないため、リンカー エラー (コンパイラ エラーではありません) が発生します。

int Dice::returnRoll() {...}
    ^^^^^^
于 2012-07-31T13:21:19.387 に答える
3

Dice::returnRoll の定義を忘れました。

于 2012-07-31T13:21:55.290 に答える
2

returnRoll を Dice:: の一部にするのを忘れていました。

あなたは単にダイスを見逃しています::

int Dice::roll()
{
    value=1+(rand()%6);
    return value;
}


int returnRoll()
{
    count=0;
    if((*result == 2)||(*result == 4)||(*result == 6))
    {
        count++;
    }
    return count;
}
于 2012-07-31T13:23:00.023 に答える
1

あなたの新しい問題に基づいて、メインファイルだけでなく両方のファイルにヘッダーファイルをインクルードしたことについて言及しなかったと思います。ヘッダーファイルでグローバル変数を定義しないでください。定義すると、このような問題が発生します。countとresultの定義を、ヘッダーではなくソースファイルに移動する必要があります。メインファイルでそれらを使用しているのはわかりませんが、追加する必要がある場合は

extern int count;
extern int* result;

ヘッダーファイルに。

さらに良いのは、グローバル変数の使用を避けることです。これは、グローバル変数が必要な状況ではありません。drawSpotsにグローバル変数を設定させる代わりに、値を返すだけではどうでしょうか。

于 2012-08-01T13:57:04.723 に答える