【发布时间】:2014-05-26 09:17:00
【问题描述】:
我有一个用 C++ 编写的 DLL,它包装了 FindFirstFile/FindNextFile/FindClose 以提供文件搜索功能:
std::vector<std::wstring> ELFindFilesInFolder(std::wstring folder, std::wstring fileMask = TEXT(""), bool fullPath = false);
此函数返回一个std::vector,其中包含与给定文件掩码匹配的给定文件夹中的文件名列表。到目前为止,一切都很好;该功能按预期工作。
不过,我需要围绕这个库编写一个 C 包装器,因为 I can't pass a vector across DLL boundaries。这让人头疼不已。
我最初以为我只是设置一个函数,它会接收一个二维wchar_t 数组,修改它以包含文件名列表,然后返回它:
bool ELFindFilesInFolder(const wchar_t* folderPath, const wchar_t* fileMask, const bool fullPath, wchar_t* filesBuffer[], size_t* filesBufferSize);
然而,这被证明是个坏主意,就像at least the second dimension's size has to be known at compile-time。我想我可以只是强制调用者创建第二维MAX_PATH(因此该函数将接收一个可变长度的文件名缓冲区列表,每个MAX_PATH long),但这似乎很混乱我。
我考虑过 Windows API 风格的包装器:
bool ELFindNextFileInFolder(const wchar_t* folderPath, const wchar_t* fileMask, const bool fullPath, wchar_t* fileBuffer, size_t* fileBufferSize, HANDLE* searchToken);
这将执行搜索,返回找到的第一个文件名,并保存FindFirstFile 提供的搜索句柄。将来对ELFindNextFileInFolder 的调用将提供此搜索句柄,从而可以轻松地从上次调用中断的地方继续:FindNextFile 将只获取保存的搜索句柄。但是,此类句柄需要通过FindClose 关闭,而C 似乎没有智能指针的C++ 概念,因此我不能保证searchToken 将永远关闭。当FindNextFile 表示没有更多结果时,我可以自己关闭一些句柄,但如果调用者在此之前放弃搜索,则会有一个浮动句柄保持打开状态。我非常希望我的图书馆表现得很好,并且不会到处泄漏 HANDLE,所以这已经结束了。我也不想提供ELCloseSearchHandle 函数,因为我不确定我是否可以信任调用者正确使用它。
有没有一种很好的、最好是单一功能的方法来包装这些 Windows API,还是我只需要从不完善的解决方案列表中选择一个?
【问题讨论】: