代码之家  ›  专栏  ›  技术社区  ›  user3797103

尝试使用DLL项目中的类时发生LNK2019错误[重复]

  •  -1
  • user3797103  · 技术社区  · 9 年前

    我正在为我的项目编写目录观察程序类。它在c++中的.dll类型项目。我使用Visual Studio 2013作为IDE。

    我遵循了以下基本步骤:

    1.创建了一个dll和c++语言类型的新项目

    2.添加了类和dllExport类型声明

    3.构建项目

    4.创建控制台应用类型的新项目

    5.向dll项目添加引用(两个项目位于不同的目录中)

    6.指向附加包含文件中的头文件路径

    但是 在编写了一些使用的代码之后。编译时,我收到以下错误

    Error   1   error LNK2019: unresolved external symbol "public: __thiscall DirectoryWatcher::DirectoryWatcher(void)" (??0DirectoryWatcher@@QAE@XZ) referenced in function "void __cdecl `dynamic initializer for 'watcher''(void)" (??__Ewatcher@@YAXXZ) C:\Users\Karthik\documents\visual studio 2013\Projects\ConsoleApplication2\ConsoleApplication2\Source.obj   ConsoleApplication2*
    

    但是Dll项目构建成功

    一开始,我在指向析构函数时出错,但在头本身中编写了实现(空的只是大括号{})之后。该错误被指向构造函数的错误替换

    她的头文件

    #define _SCL_SECURE_NO_WARNINGS
    
    #ifdef DIRECTORYWATCHER_EXPORTS
    #define APITYPE __declspec(dllexport)
    #else
    #define APITYPE __declspec(dllimport)
    #endif
    
    
    #if defined(_WIN32) 
    #define PLATFORM_WINDOWS
    #elif __APPLE__
    #define PLATFORM_MAC
    #elif __linux
    #define PLATFORM_LINUX
    #endif
    //-------------------------------------------
    // Code Begins Here
    //---------------------------------
    #ifndef DIRECTORY_WATCHER_H
    #define DIRECTORY_WATCHER_H
    
    #define USE_DIRENT
    
    
    
    //------------------------
    // Includes
    //--------------
    #include<vector>
    #include<iostream>
    #include<fstream>
    #include<string>
    #include<sys\stat.h>
    #include <tchar.h>
    #include<map>
    
    #ifdef PLATFORM_WINDOWS
    #include<Windows.h>
    #endif
    
    #ifdef USE_BOOST
    #include<boost/filesystem.hpp>
    #include <boost/uuid/uuid.hpp>
    #include <boost/uuid/uuid_io.hpp>
    #include <boost/uuid/random_generator.hpp>
    #include <boost/lexical_cast.hpp>
    #endif
    
    #ifdef USE_DIRENT
    #include <dirent.h>
    #endif
    
    using namespace std;
    
    //Meta File
    template<typename T>
    struct Meta
    {
        string Name,Path;
        size_t GUID;
         float Size;
        int Type;
    
        // Can be anything like list of name or list of animation files or list of folder with a folder
         vector<T> MetaInfo;
    
    };
    
    
    
    //---------------------------------------------
    // TYPE DEFS
    //-------------------------------------
    
    APITYPE typedef  hash<string> HashFunction;
    APITYPE typedef Meta<string> FOLDER_META;
    
    
    struct ChildrenTree
    {
        vector<Meta<string>> Children;
    
    };
    struct DirectoryTree
    {
    
        string ParentPath;
        //map<Children Name,Related Info>
        map<string, FOLDER_META> Child;
    
    };
    
    struct Changed_Data
    {
        FOLDER_META Old;
        FOLDER_META New;
    };
    
    //------------------------------------
    //operators
    //------------------------------------
    
    
    #ifdef USE_DIRENT
    class DirectoryWatcher
    {
        //-----------------Type Defs------------------------
    
        //typedef Meta<string> FOLDER_META;
    public:
        //Varaibles
        FOLDER_META defaultMeta;
        Meta<DirectoryTree> TreeMeta;
    
        // Default Constructor
        DirectoryWatcher(void);
    
    
        ~DirectoryWatcher(void){}  // Eror at first pointed to the destructor which was solved by defining it here its self 
    
        // Obtains a list of files and folders in a directory
        APITYPE void GetList(const string&, vector<FOLDER_META>* ReturnValue ,FOLDER_META* ThisDireMeta);
    
        // Searches and Returns the pathto the file
        APITYPE bool FindFile(const string& Path
            ,const string& FileName // File Name
            , string* Ret //Path Returned 
            );
    
        //Update and check to see if a file as moved or added or changed 
        // Monitor(vector<FOLDER_META>* ChangedFiles,bool* FilesChanged -> return types); 
        APITYPE void Monitor(vector<Changed_Data>* ChangedFiles,bool* FilesChanged);
    
        // Creates a GUID for a file 
        APITYPE size_t CreateGUID(const string& fileName);
    
        //Export metadata
        APITYPE void ExportMeta(const string& Path,FOLDER_META meta);
        // Get the meta data
        APITYPE  void GetFolderMeta(const string& Path,Meta<string> * ReturnValue );
    
        //InitalizeMethod 
        // False if path invalid
        // true if path correct
        APITYPE bool Init(const string& Path //Path to the Project folder (The folder to watch)
            );
    
        APITYPE bool Init(const string& Path //Path to the Project folder (The folder to watch)
            ,vector<FOLDER_META> * Returnmetas);
    
        APITYPE void MakeDir(const string& path);
    
    
    private:
    
        string Project_Path;
        DIR* dir = nullptr;
        DIR* MainDir = nullptr;
        struct dirent* ent = nullptr;
        DIR* tempDir = nullptr;
        DirectoryTree Tree;
        HashFunction hashFunc;
    
        //Dpeth Search 
        DirectoryTree UnVisited;
    
    
        //-------------------------------------
        // Windows Specifif cCode
        //---------------------------------
        HANDLE ChangeNotifications[2];
        TCHAR lpDrive[4];
        TCHAR lpFile[_MAX_FNAME];
        TCHAR lpExt[_MAX_EXT];
        DWORD Notifications; 
    
    
    
        // Private methods
        APITYPE long GetFolderSize( const string& Path);
        APITYPE bool CheckPathValid(const string& Path);
    
        APITYPE void RefreshFiles(vector<Changed_Data>* ChangedFiles,const string& path,bool OnlyThisFolder);
        APITYPE void RefreshTree(vector<Changed_Data>* ChangedFiles, const string& path);
        APITYPE void CreateTree(const string& Path );
    
        APITYPE void SaveTree();
        APITYPE void LoadTree();
        APITYPE bool AreChildEqual(const FOLDER_META& metaA,const FOLDER_META& metaB );
    };
    #endif
    
    #endif // !DIRECTORY_WATCHER_H
    

    *我省略了实现部分,因为它非常大,但这里只有构造函数*

    DirectoryWatcher.cpp目录

      DirectoryWatcher::DirectoryWatcher(void)
        {
    
          Project_Path = "";
          dir = nullptr;
          MainDir = nullptr;
          ent = nullptr;
          tempDir = nullptr;
        }
    

    测试应用程序

    源.cpp

    #include<DirectoryWatcher.h>
    
    
    using namespace std;
    
    
    
    
    DirectoryWatcher watcher;
    
    // omitted part of code 
    int main(int argv, char* argc) 
    {
        string Path;
        cout << "enterPath";
        cin >> Path;
    
        bool ISCahnged;
        vector<FOLDER_META> metas,Returnvalues;
        vector<Changed_Data> changedDatas;
        watcher.Init(Path, &Returnvalues);
    
        while (true)
        {
            ISCahnged = false;
            watcher.Monitor(&changedDatas, &ISCahnged);
    
            if (ISCahnged)
            {
                for each (Changed_Data var in changedDatas)
                {
                    OutChangedData(var);
                }
            }
    
        }
    
        return 0;
    }
    

    对于较小的代码,省略了几行

    有人能帮忙解决这个问题吗

    非常感谢。

    1 回复  |  直到 9 年前
        1
  •  1
  •   Community Egal    7 年前

    您需要从dll导出类。这里有一个非常好的答案: Exporting a C++ class from a DLL