2

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

我想了解为什么我收到错误 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;
}
4

2 回答 2

2

您得到的错误来自linker,它告诉您它找不到and函数的定义(这两个函数都是从您的函数中引用的)。ReportErrorOptionsmain

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

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

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

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

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

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

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

于 2013-08-04T16:47:51.583 回答