用vc++函数构建DLL是不可访问的

Building a DLL with VC++ function is inaccessible

本文关键字:访问 DLL vc++ 函数 构建      更新时间:2023-10-16

今天我需要一个小库来递归地列出一个文件夹和所有子文件夹中的所有文件。所以我决定创建一个小的库,它非常简单,只包含两个函数:

bool __cdecl isDir(std::string dir);
void __cdecl listDir(std::string dir, std::vector<std::string> &files, bool recursive);

这些功能是不言自明的。

它包含一个头文件,它定义了一个类FR,我使用

导出它

__declspec(dllexport)

我费心做这个小库的原因是它可以在将来的项目中使用,而不必一直将源文件合并到我的项目中。

下面是我尝试调用其中一个函数的方式:

FR *clazz = new FR();
clazz->isDir("C:/path/to/dir");

生成的错误如下:
智能感知:函数"FR::isDir"(在"C:devFileRecursionDLLinc FR .h"的第11行声明)无法访问

[fr.cpp]

#include "fr.h"
using namespace std;
BOOL APIENTRY DllMain(HANDLE hModule,
    DWORD  ul_reason_for_call,
    LPVOID lpReserved)
{
    return TRUE;
}
DllExport bool __cdecl FR::isDir(string dir){
    struct stat fileInfo;
    stat(dir.c_str(), &fileInfo);
    if (S_ISDIR(fileInfo.st_mode)){
        return true;
    }
    else{
        return false;
    }
}
DllExport void __cdecl FR::listDir(string dir, vector<string> &files, bool recursive){
    DIR *dp; //create the directory object
    struct dirent *entry; //create the entry structure
    dp = opendir(dir.c_str()); //open directory by converting the string to const char*
    if (dir.at(dir.length() - 1) != '/'){
        dir = dir + "/";
    }
    if (dp != NULL){ //if the directory isn't empty
        while (entry = readdir(dp)){ //while there is something in the directory
            if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0){ //and if the entry isn't "." or ".."
                if (isDir(dir + entry->d_name) == true && recursive == true){//check if the new path is a directory, and if it is (and recursion is specified as true), recurse.
                    files.push_back(string(entry->d_name)); //add entry to the list of files
                    listDir(dir + entry->d_name, files, true); //recurse
                }
                else{
                    files.push_back(string(entry->d_name));//add the entry to the list of files
                }
            }
        }
        (void)closedir(dp); //close directory
    }
    else{
        perror("Couldn't open the directory.");
    }
}

[fr.h]

#ifndef FR_H
#define FR_H
#define DllExport   __declspec( dllexport ) 
#include<dirent.h>
#include<vector>
class DllExport FR
{
    bool __cdecl isDir(std::string dir);
    void __cdecl listDir(std::string dir, std::vector<std::string> &files, bool recursive);
};
#endif

注意:对已经这样做的库的引用也会很感激!

提前感谢!

class成员默认为private, struct成员默认为public


这就是说,为什么不做一个通用的和简单的创建和使用头文件模块,而不是添加一个复杂的特定于编译器的DLL。

此外,对于Windows编程最好使用宽字符串(即Unicode)。


的例子:

#pragma once
// Copyright (c) 2014 Alf P. Steinbach
#undef UNICODE
#define UNICODE
#include <windows.h>
#include <string>           // std::wstring
#include <vector>           // std::vector
namespace filesystem{
    using std::wstring;
    using std::vector;
    inline
    auto path_join( wstring const& a, wstring const& b )
        -> wstring
    {
        int const len_a = a.length();
        int const len_b = b.length();
        if( len_a == 0 ) { return b; }
        if( len_b == 0 ) { return a; }
        wstring result = a;
        if( a[len_a - 1] == L'' )
        {
            if( b[0] == L'' ) { result.resize( len_a - 1 ); }
        }
        else if( b[0] != L'' )
        {
            result += L'';
        }
        result += b;
        return result;
    }

    enum Recursion { no_recursion, recursive };
    inline
    auto directory_entries( wstring const& directory_path, Recursion const r = no_recursion )
        -> vector<wstring>
    {
        vector<wstring> result;
        WIN32_FIND_DATA state = {};
        HANDLE const h = FindFirstFile( path_join( directory_path, L"*.*" ).c_str(), &state );
        for(
            bool more = (h != INVALID_HANDLE_VALUE);
            more;
            more = !!FindNextFile( h, &state )
            )
        {
            result.push_back( state.cFileName );
            if( r == recursive && !!(state.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
            {
                // TODO: Check that this isn't a "." or ".." or (hard problem) circular symlink entry.
                bool const is_true_subdirectory = false;        // <-- Here.
                if( is_true_subdirectory )
                {
                    auto const sub_entries = directory_entries(
                        path_join( directory_path, state.cFileName ), recursive
                        );
                    for( auto const& e : sub_entries )
                    {
                        result.push_back( e );
                    }
                }
            }
        }
        FindClose( h );
        return result;
    }
}  // namespace filesystem