C++ 奇怪的未解决的外部错误

C++ 奇怪的未解决的外部错误,c++,winapi,gdi,unresolved-external,C++,Winapi,Gdi,Unresolved External,我遇到一些未解决的外部错误,我似乎无法找到解决方案: 1>MyApp.obj : error LNK2019: unresolved external symbol "public: void __thiscall Path::AddPoint(struct Point2D const &)" (?AddPoint@Path@@QAEXABUPoint2D@@@Z) referenced in function "public: static long __stdcall MyAp

我遇到一些未解决的外部错误,我似乎无法找到解决方案:

1>MyApp.obj : error LNK2019: unresolved external symbol "public: void __thiscall Path::AddPoint(struct Point2D const &)" (?AddPoint@Path@@QAEXABUPoint2D@@@Z) referenced in function "public: static long __stdcall MyApp::WndProc(struct HWND__ *,unsigned int,unsigned int,long)" (?WndProc@MyApp@@SGJPAUHWND__@@IIJ@Z)
1>MyApp.obj : error LNK2019: unresolved external symbol "public: void __thiscall Path::ClrPath(void)" (?ClrPath@Path@@QAEXXZ) referenced in function "public: static long __stdcall MyApp::WndProc(struct HWND__ *,unsigned int,unsigned int,long)" (?WndProc@MyApp@@SGJPAUHWND__@@IIJ@Z)
1>MyApp.obj : error LNK2019: unresolved external symbol "public: enum TOOL __thiscall Path::GetTool(void)" (?GetTool@Path@@QAE?AW4TOOL@@XZ) referenced in function "public: static long __stdcall MyApp::WndProc(struct HWND__ *,unsigned int,unsigned int,long)" (?WndProc@MyApp@@SGJPAUHWND__@@IIJ@Z)
1>MyApp.obj : error LNK2019: unresolved external symbol "public: void __thiscall Path::SetTool(enum TOOL)" (?SetTool@Path@@QAEXW4TOOL@@@Z) referenced in function "public: static long __stdcall MyApp::WndProc(struct HWND__ *,unsigned int,unsigned int,long)" (?WndProc@MyApp@@SGJPAUHWND__@@IIJ@Z)
奇怪的是,我很确定我把所有的东西都写对了。另外,该类中始终有一个函数可以工作:DrawTo

我试图删除其他函数的“内联”声明,但这似乎无关紧要

我还尝试过重建它一次,只是在两个函数之间添加了一些额外的端点,然后编译了它!下一次我尝试编译时,它又不起作用了

所以我不能完全确定我是否做错了什么,或者是编译器。。。默认VS2010编译器实际上,该编译器的名称是什么?[评论或编辑]

有人知道这意味着什么吗

以下是相关代码:如果您需要查看更多内容,请发表评论,我将进行编辑

路径h Path.cpp MyApp.h MyApp::WndProc
去掉那些内联声明,因为代码不是内联的,除非它实际上在头文件中。然后执行一个干净的构建,然后执行完整的构建。

去掉那些内联声明,因为代码不是内联的,除非它实际上在头文件中。然后进行一个干净的构建,然后进行完整的构建。

唯一有效的函数是未内联的函数

如果你仔细想想,你就会意识到这是有道理的。当编译器编译MyApp.cpp时,它发现您正在调用一个声明为内联的方法。因此编译器需要复制该方法的代码,而不仅仅是调用它。问题是,编译器如何知道该方法的定义位置?编译器可以看到它的唯一方式是,如果内联方法的实现在Path.h中,或者在MyApp.cpp包含的其他头文件中


因此,最简单的解决方案是将所有这些内联方法的实现移动到Path.h文件中。

唯一有效的函数是未内联的函数

如果你仔细想想,你就会意识到这是有道理的。当编译器编译MyApp.cpp时,它发现您正在调用一个声明为内联的方法。因此编译器需要复制该方法的代码,而不仅仅是调用它。问题是,编译器如何知道该方法的定义位置?编译器可以看到它的唯一方式是,如果内联方法的实现在Path.h中,或者在MyApp.cpp包含的其他头文件中


因此,最简单的解决方案是将所有这些内联方法的实现移到Path.h文件中。

这似乎并不重要,就像我写的一样,我以前完全按照这种方式编译了它,而且它工作正常。现在,当我试图删除内联声明时,我仍然会收到相同的错误。抱歉,回复太晚。顺便说一句,我睡着了:pUpdate:最近,我删除了内联声明并重新编译。它不起作用。在那之后,我在Path.cpp中的两个函数体之间添加了一条新行,它编译后没有任何意义,对吗?。之后,我重新添加了内联声明,并编译了。。。这到底是怎么回事?我的灵力告诉我,你有一个肮脏的建造状态,只需要重建干净。或者您的path.h文件可能包含在path.cpp中,但不是Visual Studio中的项目文件之一。可能您预编译的标题已过时。如果有疑问,请从命令行执行del/s*.obj,并对*.pch、*.lib、*.dll、*.exe执行相同的操作。或者只是删除输出目录,调试并释放目录。当我遇到毫无意义的链接器问题时,这对我来说总是有效的。这似乎并不重要。就像我写的一样,我以前就这样编译了它,它起了作用。现在,当我试图删除内联声明时,我仍然会收到相同的错误。抱歉,回复太晚。顺便说一句,我睡着了:pUpdate:最近,我删除了内联声明并重新编译。它不起作用。在那之后,我在Path.cpp中的两个函数体之间添加了一条新行,它编译后没有任何意义,对吗?。之后,我重新添加了内联声明,并编译了。。。这到底是怎么回事?我的灵力告诉我,你有一个肮脏的建造状态,只需要重建干净。或者您的path.h文件可能包含在path.cpp中,但不是Visual Studio中的项目文件之一。可能您预编译的标题已过时。如果有疑问,请从命令行执行del/s*.obj,并对*.pch、*.lib、*.dll、*.exe执行相同的操作。或者只是删除输出目录,调试并释放目录。当我遇到毫无意义的链接器问题时,这对我来说总是有效的。
#pragma once
#ifndef PATH_H
#define PATH_H

#include "Defines.h"
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>

#include "MyVector.h"

#include "Point2D.h"
#include "Tool.h"

class Path
{
public:
    Path();
    virtual ~Path();

    bool DrawTo(HDC hDC);

    inline void AddPoint(const Point2D& rkPoint);
    inline Point2D GetPointAt(int iIndex) const;
    inline int GetPointCount() const;

    inline TOOL GetTool();
    inline void SetTool(TOOL t);
    inline void SetColor1(COLORREF);
    inline void SetColor2(COLORREF);

    inline void ClrPath();

private:
    MyVector<Point2D> m_PointVector;
    TOOL m_Tool;

    COLORREF m_Colour1;
    COLORREF m_Colour2;
};

#endif
#include "Path.h"

Path::Path()
{
    m_Tool = Tool_Pen;

    m_Colour1 = RGB(0,0,0);
    m_Colour2 = RGB(255,255,255);
}

Path::~Path()
{}

bool Path::DrawTo(HDC hDC)
{
    if(hDC == NULL || m_PointVector.GetLength() <= 0) {
        return false;
    }

    switch (m_Tool) {
    case Tool_Pen:
        {
            //////
            break;
        }
    case Tool_Line:
        {
            /////
            break;
        }
    case Tool_Ellipse:
        {
            //////
            break;
        }
    case Tool_Rectangle:
        {
            //////
            break;
        }
    case Tool_LineTrack:
        {
            //////
            break;
        }
    }

    return true;
}

Point2D Path::GetPointAt(int iIndex) const {
    return m_PointVector.At(iIndex);
}

int Path::GetPointCount() const {
    return m_PointVector.GetLength();
}

void Path::AddPoint(const Point2D& rkPoint) {
    m_PointVector.PushBack(rkPoint);
}

TOOL Path::GetTool() {
    return m_Tool;
}

void Path::SetTool(TOOL t) {
    m_Tool = t;
}

void Path::SetColor1(COLORREF col) {
    m_Colour1 = col;
}

void Path::SetColor2(COLORREF col) {
    m_Colour2 = col;
}

void Path::ClrPath() {
    m_PointVector.ClrAll();
}
#pragma once
#ifndef MYAPP_H
#define MYAPP_H

#include "Defines.h"
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <string>
#include <iostream>

//app includes:
#include "MyHelperFuncs_Win32.h"
#include "BitmapPainter.h"
#include "Path.h"
//-------------

class MyApp 
{
public:
    MyApp();
    virtual ~MyApp();
    static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    void Paint();

private:
    void InitWindows();

    HWND m_hWnd;
    HDC m_hDC;
    PAINTSTRUCT m_PaintStruct;

    //app-specific:
    BitmapPainter* m_pBitmapPainter;
    Path* m_pPath;
    //------------
};

#endif
LRESULT MyApp::WndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
    if(iMsg == WM_CREATE)
    {
        CREATESTRUCT *pCS = (CREATESTRUCT*)lParam;
        SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG)pCS->lpCreateParams);
    }
    else
    {
        //retrieve the stored "this" pointer
        MyApp* pApp = (MyApp*)GetWindowLongPtr(hWnd, GWLP_USERDATA);

        switch (iMsg)
        {
            case WM_PAINT:
                {
                pApp->Paint();
                return 0;
                }

            case WM_COMMAND:
            {
                int wmId    = LOWORD(wParam);
                int wmEvent = HIWORD(wParam);

                // Parse the menu selections:
                switch (wmId)
                {
                case IDM_NEW:
                    {
                    //////
                    return 0;
                case IDM_LOAD:
                    {
                    //////
                    return 0;
                    }
                case IDM_SAVE:
                    {
                    //////
                    return 0;
                    }
                case IDM_SAVEAS:
                    {
                    //////
                    return 0;
                    }
                case IDM_EXIT:
                    {
                    DestroyWindow(hWnd);
                    return 0;
                    }
                case IDM_COLOURMAIN:
                    {
                    //////
                    return 0;
                    }
                case IDM_COLOURSECONDARY:
                    {
                    //////
                    return 0;
                    }
                case IDM_PEN:
                    {
                        pApp->m_pPath->SetTool(Tool_Pen);
                        return 0;
                    }
                case IDM_LINE:
                    {
                        pApp->m_pPath->SetTool(Tool_Line);
                        return 0;
                    }
                case IDM_ELLIPSE:
                    {
                        pApp->m_pPath->SetTool(Tool_Ellipse);
                        return 0;
                    }
                case IDM_RECTANGLE:
                    {
                        pApp->m_pPath->SetTool(Tool_Rectangle);
                        return 0;
                    }
                case IDM_LINETRACK:
                    {
                        pApp->m_pPath->SetTool(Tool_LineTrack);
                        return 0;
                    }
                default:
                    {
                    //////
                    return 0;
                    }
                }
            }

            case WM_LBUTTONUP:
                {
                    OutputDebugString(_T("Left Button Up\n "));
                    if(wParam & MK_CONTROL)OutputDebugString(_T("The CTRL key is down.\n "));
                    int x = LOWORD(lParam);
                    int y = HIWORD(lParam);

                    switch(pApp->m_pPath->GetTool()) {
                        case Tool_Pen:
                            {
                            pApp->m_pPath->DrawTo(pApp->m_hDC);
                            pApp->m_pPath->ClrPath();
                            InvalidateRect(pApp->m_hWnd,NULL,true);
                            }
                    }

                    return 0;
                }

            case WM_LBUTTONDOWN:
                {
                    OutputDebugString(_T("Left Button Down\n "));
                    if(wParam & MK_CONTROL)OutputDebugString(_T("The CTRL key is down.\n "));
                    int x = LOWORD(lParam);
                    int y = HIWORD(lParam);

                    return 0;
                }

            case WM_RBUTTONUP:
                {
                    OutputDebugString(_T("Right Button Up\n "));
                    if(wParam & MK_CONTROL)OutputDebugString(_T("The CTRL key is down.\n "));
                    int x = LOWORD(lParam);
                    int y = HIWORD(lParam);

                    return 0;
                }
            case WM_MOUSEMOVE:
                {
                    OutputDebugString(_T("Mouse Moved\n "));
                    if(wParam & MK_CONTROL)OutputDebugString(_T("The CTRL key is down.\n "));
                    int x = LOWORD(lParam);
                    int y = HIWORD(lParam);
                    std::cout <<"Mouse Position: x="  << x << " y=" << y << "\n";

                    if (wParam & MK_LBUTTON) {
                        switch(pApp->m_pPath->GetTool()) {
                        case Tool_Pen:
                            {
                            Point2D p;
                            p.x = x;
                            p.y = y;
                            pApp->m_pPath->AddPoint(p);
                            InvalidateRect(pApp->m_hWnd,NULL,true);
                            }
                        }
                    }

                    return 0;
                }

            case WM_DESTROY:
                {
                PostQuitMessage(0);
                return 0;
                }
        }
    }
    return DefWindowProc (hWnd, iMsg, wParam, lParam) ;
}