【问题标题】:LNK2019 error when building solution. Why?构建解决方案时出现 LNK2019 错误。为什么?
【发布时间】:2013-08-04 16:38:21
【问题描述】:

我确信过去已经解决了这个问题。我很抱歉。

我想了解为什么我会收到错误 LNK2019。
以及采取什么方向来解决这个问题。

Errors are LNK2019:
unresolved external symbol __imp__ReportError referenced in function _wmain
unresolved external symbol __imp__Options referenced in function _wmain

当我在 Visual Studio 2010 及更高版本中构建解决方案时会发生这种情况。
上述方法的头文件内容描述如下:

LIBSPEC DWORD Options (int, LPCTSTR *, LPCTSTR, ...);
LIBSPEC DWORD Options (int, LPCTSTR *, LPCTSTR, ...);

主要代码:

#include "Everything.h"

BOOL TraverseDirectory(LPTSTR, LPTSTR, DWORD, LPBOOL);
DWORD FileType(LPWIN32_FIND_DATA);
BOOL ProcessItem(LPWIN32_FIND_DATA, DWORD, LPBOOL);

int _tmain(int argc, LPTSTR argv[])
{
    BOOL flags[MAX_OPTIONS], ok = TRUE;
    TCHAR searchPattern[MAX_PATH + 1], currPath[MAX_PATH_LONG+1], parentPath[MAX_PATH_LONG+1];
    LPTSTR pSlash, pSearchPattern;
    int i, fileIndex;
    DWORD pathLength;

    fileIndex = Options(argc, argv, _T("Rl"), &flags[0], &flags[1], NULL);


    pathLength = GetCurrentDirectory(MAX_PATH_LONG, currPath); 
    if (pathLength == 0 || pathLength >= MAX_PATH_LONG) { /* pathLength >= MAX_PATH_LONG (32780) should be impossible */
        ReportError(_T("GetCurrentDirectory failed"), 1, TRUE);
    }

    if (argc < fileIndex + 1) 
        ok = TraverseDirectory(currPath, _T("*"), MAX_OPTIONS, flags);
    else for (i = fileIndex; i < argc; i++) {
        if (_tcslen(argv[i]) >= MAX_PATH) {
            ReportError(_T("The command line argument is longer than the maximum this program supports"), 2, FALSE);
        }
        _tcscpy(searchPattern, argv[i]);
        _tcscpy(parentPath, argv[i]);

        pSlash = _tstrrchr(parentPath, _T('\\')); 
        if (pSlash != NULL) {
            *pSlash = _T('\0');
            _tcscat(parentPath, _T("\\"));         
            SetCurrentDirectory(parentPath);
            pSlash = _tstrrchr(searchPattern, _T('\\'));  
            pSearchPattern = pSlash + 1;
        } else {
            _tcscpy(parentPath, _T(".\\"));
            pSearchPattern = searchPattern;
        }
        ok = TraverseDirectory(parentPath, pSearchPattern, MAX_OPTIONS, flags) && ok;
        SetCurrentDirectory(currPath);  
    }

    return ok ? 0 : 1;
}

static BOOL TraverseDirectory(LPTSTR parentPath, LPTSTR searchPattern, DWORD numFlags, LPBOOL flags)
{
    HANDLE searchHandle;
    WIN32_FIND_DATA findData;
    BOOL recursive = flags[0];
    DWORD fType, iPass, lenParentPath;
    TCHAR subdirectoryPath[MAX_PATH + 1];

    /* Open up the directory search handle and get the
        first file name to satisfy the path name.
        Make two passes. The first processes the files
        and the second processes the directories. */

    if ( _tcslen(searchPattern) == 0 ) {
        _tcscat(searchPattern, _T("*"));
    }
    /* Add a backslash, if needed, at the end of the parent path */
    if (parentPath[_tcslen(parentPath)-1] != _T('\\') ) { /* Add a \ to the end of the parent path, unless there already is one */
        _tcscat (parentPath, _T("\\"));
    }


    /* Open up the directory search handle and get the
        first file name to satisfy the path name. Make two passes.
        The first processes the files and the second processes the directories. */

    for (iPass = 1; iPass <= 2; iPass++) {
        searchHandle = FindFirstFile(searchPattern, &findData);
        if (searchHandle == INVALID_HANDLE_VALUE) {
            ReportError(_T("Error opening Search Handle."), 0, TRUE);
            return FALSE;
        }


        do {

            fType = FileType(&findData);
            if (iPass == 1) /* ProcessItem is "print attributes". */
                ProcessItem(&findData, MAX_OPTIONS, flags);

            lenParentPath = (DWORD)_tcslen(parentPath);
            /* Traverse the subdirectory on the second pass. */
            if (fType == TYPE_DIR && iPass == 2 && recursive) {
                _tprintf(_T("\n%s%s:"), parentPath, findData.cFileName);
                SetCurrentDirectory(findData.cFileName);
                if (_tcslen(parentPath) + _tcslen(findData.cFileName) >= MAX_PATH_LONG-1) {
                    ReportError(_T("Path Name is too long"), 10, FALSE);
                }
                _tcscpy(subdirectoryPath, parentPath);
                _tcscat (subdirectoryPath, findData.cFileName); /* The parent path terminates with \ before the _tcscat call */
                TraverseDirectory(subdirectoryPath, _T("*"), numFlags, flags);
                SetCurrentDirectory(_T("..")); /* Restore the current directory */
            }

            /* Get the next file or directory name. */

        } while (FindNextFile(searchHandle, &findData));

        FindClose(searchHandle);
    }
    return TRUE;
}

static DWORD FileType(LPWIN32_FIND_DATA pFileData)
{
    BOOL isDir;
    DWORD fType;
    fType = TYPE_FILE;
    isDir =(pFileData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
    if (isDir)
        if (lstrcmp(pFileData->cFileName, _T(".")) == 0
                || lstrcmp(pFileData->cFileName, _T("..")) == 0)
            fType = TYPE_DOT;
        else fType = TYPE_DIR;
    return fType;
}

static BOOL ProcessItem(LPWIN32_FIND_DATA pFileData, DWORD numFlags, LPBOOL flags)
{
    const TCHAR fileTypeChar[] = {_T(' '), _T('d')};
    DWORD fType = FileType(pFileData);
    BOOL longList = flags[1];
    SYSTEMTIME lastWrite;

    if (fType != TYPE_FILE && fType != TYPE_DIR) return FALSE;

    _tprintf(_T("\n"));
    if (longList) {
        _tprintf(_T("%c"), fileTypeChar[fType - 1]);
        _tprintf(_T("%10d"), pFileData->nFileSizeLow);
        FileTimeToSystemTime(&(pFileData->ftLastWriteTime), &lastWrite);
        _tprintf(_T("   %02d/%02d/%04d %02d:%02d:%02d"),
                lastWrite.wMonth, lastWrite.wDay,
                lastWrite.wYear, lastWrite.wHour,
                lastWrite.wMinute, lastWrite.wSecond);
    }
    _tprintf(_T(" %s"), pFileData->cFileName);
    return TRUE;
}

【问题讨论】:

    标签: c windows visual-studio-2010 visual-studio-2012


    【解决方案1】:

    您收到的错误来自 链接器,它告诉您它找不到 ReportErrorOptions 函数的 定义(两者其中引用自您的main 函数)。

    你说你已经包含了一个包含这些函数的头文件,但是那个头文件只包含了这些函数的声明。你知道,就像他们的签名一样。它没有功能的主体(实现)。你需要定义

    您编写的函数的定义通常位于*.cpp 文件中。如果您编写了这些函数,请确保包含其定义的代码文件已添加到您的项目中。

    对于您尚未编写的函数(即是可重用代码库的一部分),您通常为链接器提供一个 *.lib 文件,其中包含调用函数所需的内容。如果这些函数来自库,请确保已将它们随附的 *.lib 文件添加到链接器将搜索的文件列表中。要在 Visual Studio 中执行此操作,请执行以下步骤:

    1. 在解决方案资源管理器中右键单击您的项目,然后打开其属性。
    2. 展开“链接器”类别,并选择“输入”节点。
    3. 单击“附加依赖项”字段,然后按 ... 按钮。
    4. 在出现的文本框中的新行中输入*.lib 文件的名称。

    【讨论】:

    • 你的解释真好!我忘了包括其他源文件。这些函数的定义一直在那些源文件中。傻我。非常感谢。
    【解决方案2】:

    仅仅因为你在头文件中声明了一个函数,并不意味着它在任何地方都有一个主体。

    链接错误表明该函数没有主体。

    这可能是因为您没有链接到正确的库(.lib 文件)。

    【讨论】:

    • 嗨,阿贝伦奇。这个提示已经足够了。我很感激。
    猜你喜欢
    • 2019-03-16
    • 1970-01-01
    • 2017-11-18
    • 2012-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-12
    相关资源
    最近更新 更多