c ++错误LNK2019:未解析的外部符号.obj

时间:2014-04-05 17:32:51

标签: c++ lnk2019 unresolved-external .obj

首先,我知道有超过一百个相似的帖子出现同样的错误,其全部原因是因为给出的错误是无用的。

我已经通过Google搜索了20多种解决方案,但仍然无法弄清楚代码中的错误位置,因此我提出了这个问题。

这是错误:

Error   2   error LNK1120: 1 unresolved externals   C:\Users\Kevin Cruijssen\Documents\Visual Studio 2013\Projects\ClientOSCPP-trunk\ cpp-and-so-client\ClientOSCPP\Debug\ClientOSCPP.exe   ClientOSCPP

Error   1   error LNK2019: unresolved external symbol "private: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __thiscall CommandSyncHandler::FileJustRenamed(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (?FileJustRenamed@CommandSyncHandler@@AAE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V23@@Z) referenced in function "private: void __thiscall CommandSyncHandler::ReadFilesToSync(class Socket *)" (?ReadFilesToSync@CommandSyncHandler@@AAEXPAVSocket@@@Z)    C:\Users\Kevin Cruijssen\Documents\Visual Studio 2013\Projects\ClientOSCPP-trunk\ cpp-and-so-client\ClientOSCPP\CommandSyncHandler.obj  ClientOSCPP

以下是发生错误的类:

CommandSyncHandler.h:

#pragma once

#include "CommandHandler.h"

class CommandSyncHandler : public CommandHandler
{
private:
    CommandSyncHandler(void);
    CommandSyncHandler(const char* szCommand);

    static CommandSyncHandler m_cSyncHandler;
    std::string localFolder, remoteFolder;

    std::string FileJustRenamed(std::string filename);

    void ReadFilesToSync(Socket* socket);

public:
    virtual ~CommandSyncHandler(void);

    virtual CommandHandler* Clone() const;

    virtual void HandleCommand(Socket* socket, std::vector<std::string>& rvParams);
};

CommandSyncHandler.cpp:

#include "stdafx.h"

#include "CommandSyncHandler.h"
#include "Constants.h"
#include "FileReader.h"
#include "FileHandler.h"
#include "CommandFactory.h"

#include <iostream>
#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>
#include <time.h>

CommandSyncHandler CommandSyncHandler::m_cSyncHandler("SYNC");

CommandSyncHandler::CommandSyncHandler(const char* szCommand) : CommandHandler(szCommand){}

CommandSyncHandler::CommandSyncHandler(void){}

CommandSyncHandler::~CommandSyncHandler(void){}

CommandHandler* CommandSyncHandler::Clone() const{
    return new CommandSyncHandler;
}

std::string FileJustRenamed(std::string filename){
    std::string result = "";

    /*std::string filedir;
    const size_t last_slasg_index = filename.rfind(PATH_SEPARATOR);
    if (std::string::npos != last_slasg_index)
        filedir = filename.substr(0, last_slasg_index);
    filedir = SERVER_DIRECTORY + filedir.substr(BASE_DIRECTORY.length());

    // First check wether the file is the exact same size 
    // before continueing to compare the bytes/md5-hashes (which takes longer)
    FileReader* reader1;
    try{
        reader1 = new FileReader(filename.c_str());
    }
    catch (const char* e){
        (void)e;

        std::cout << "Cannot open file: " << filename << std::endl;
        return result = "";
    }
    int size1 = reader1->FileSize();

    // Loop through all the files in the Server's same Directory
    FileHandler fileHandler;
    std::vector<std::string> filesInDir;
    fileHandler.GetFiles(filedir.c_str(), filesInDir);
    for each (std::string curfile in filesInDir) {
        bool continueLoop = true;

        FileReader* reader2 = NULL;
        try{
            reader2 = new FileReader(curfile.c_str());
        }
        catch (const char* e){
            (void)e;

            std::cout << "Cannot open file: " << filename << std::endl;
            continueLoop = false;
        }

        if (continueLoop){
            int size2 = reader2->FileSize();

            if (size1 != size2){
                result = "";
                continueLoop = false;
            }

            if (continueLoop){
                // If the size of both files are the same, we continue to check if they are the exact same file
                // We do this by comparing the byte-blocks of the file-buffer
                const int BUFFER_SIZE = 1024;

                std::ifstream file1(filename.c_str(), std::ios::in | std::ios::binary);
                std::ifstream file2(curfile.c_str(), std::ios::in | std::ios::binary);

                if (!file1.good() || !file2.good()){
                    result = "";
                    continueLoop = false;
                }

                if (continueLoop){
                    std::streamsize bytesCount1 = 0;
                    std::streamsize bytesCount2 = 0;
                    char* buffer1 = new char[BUFFER_SIZE]();
                    char* buffer2 = new char[BUFFER_SIZE]();

                    do {
                        file1.read(buffer1, BUFFER_SIZE);
                        file2.read(buffer2, BUFFER_SIZE);
                        bytesCount1 = file1.gcount();
                        bytesCount2 = file2.gcount();

                        if (bytesCount1 != bytesCount2 || std::memcmp(buffer1, buffer2, bytesCount1) != 0)
                            continueLoop = false;
                    } while (file1.good() || file2.good());

                    if (continueLoop)
                        return curfile;
                }
            }
        }
    }*/

    return result = "";
}

void CommandSyncHandler::HandleCommand(Socket* socket, std::vector<std::string>& rvParams){
    if (rvParams.size() < 3)
        throw "Not enough parameters specified";

    localFolder = rvParams.at(1);
    remoteFolder = rvParams.at(2);
    std::string filePath = BASE_DIRECTORY;
    filePath.append(localFolder);

    rvParams.erase(rvParams.begin() + 1);
    std::string command = BuildCommand(rvParams);
    socket->writeline(command.c_str());

    /*| TODO
    struct stat file_stats;
    struct tm* clock;
    stat(filePath.c_str(), &file_stats);
    clock = gmtime(&(file_stats.st_mtime));
    mktime(clock);
    */

    std::vector<std::string> vFiles;
    std::string directory = BASE_DIRECTORY;
    directory.append(localFolder);

    FileHandler handler;
    handler.GetFiles(directory.c_str(), vFiles);

    for (std::string file : vFiles){

        file.erase(0, BASE_DIRECTORY.size());
        //Translate local folder to remote folder to sync
        int index = file.find(localFolder);
        if (index >= 0){
            file.erase(index, localFolder.size());
            file.insert(index, remoteFolder);
        }
        socket->writeline(file.c_str());
    }
    socket->writeline("");
    //std::string file = remoteFolder;
    //file.append(PATH_SEPARATOR);
    //file.append(ent->d_name);
    //socket->writeline(file.c_str());

    ReadFilesToSync(socket);
}

void CommandSyncHandler::ReadFilesToSync(Socket* socket){
    char* returnFile = new char[MAXPATH + 1];
    char* returnLine = new char[MAXREAD + 1];
    CommandHandler* handler = CommandFactory::create("PUT");

    std::vector<std::string> vFiles;
    while (socket->readline(returnFile, MAXPATH) > 0)
        vFiles.push_back(std::string(returnFile));

    for (std::string remoteFile : vFiles){
        std::string file = remoteFile;
        //Translate remote folder to local folder to sync
        int index = file.find(remoteFolder);

        std::vector<std::string> vParams;
        // Check wether file is completely different or just renamed
        std::string oldFile = FileJustRenamed(file);
        if (oldFile != "") {
            vParams.push_back(std::string("REN"));
            vParams.push_back(oldFile);
            vParams.push_back(file);
        }
        else {
            // Replace file
            if (index >= 0){
                file.erase(index, remoteFolder.size());
                file.insert(index, localFolder);
            }

            vParams.push_back(std::string("PUT"));
            vParams.push_back(file);
            vParams.push_back(std::string(remoteFile));
        }

        std::cout << "Sending " << file << std::endl;
        handler->HandleCommand(socket, vParams);

        // Read feedback from put command
        while (socket->readline(returnLine, MAXREAD) > 0)
            std::string x = returnLine;//std::cout << returnLine << std::endl;
    }

    delete handler;
    delete[] returnFile;
    delete[] returnLine;

    throw "Sync completed";
}

任何人都有任何想法?因为超过2个小时后我真的希望这个固定,所以我可以继续这个糟糕的项目..

PS:FileJustRenamed函数中的所有内容都被注释掉了,所以我知道错误不在代码中的某个地方。

PSS:忽略糟糕的编程..我是C ++的新手。

PSSS:在.h和.cpp文件以及ReadFilesToSync函数中添加FileJustRenamed部分之前,一切正常。

我尝试过的一些事情:

  • 更改.h文件中函数的顺序
  • 检查我是否包含.cpp文件中的CommandSyncHandler.h
  • 取消注释FileJustRenamed中的代码(请参阅第一个PS)

我可能只是犯了一个小错误,比如header / cpp文件中的函数顺序或者一些小的遗忘(如include),但就像我说的那样,经过两个多小时后我真的有块眼睛和没有任何线索如何解决它..

所以请帮助..提前致谢。

2 个答案:

答案 0 :(得分:3)

在“CommandSyncHandler.cpp”中,在函数FileJustRenamed()的定义中,将类名CommandSyncHandler添加到函数名中,如下所示:

std::string CommandSyncHandler::FileJustRenamed(std::string filename){

答案 1 :(得分:2)

您忘了在cpp文件中的函数CommandSyncHandler的名称前添加类名FileJustRenamed

在cpp文件中尝试:

std::string CommandSyncHandler::FileJustRenamed(std::string filename){

编辑:哦,@ Gil Elad在我之前12秒发布了答案......;)