0

在 Windows 上,我正在尝试使用 的变体之一LoadLibrary()打开dll以前写入的std::filesystem::path带有ofstream.

注意:我知道 dll 编写正确,因为我可以通过在运行时链接到它以标准方式使用它。

我一直在尝试结合以下两个答案中的方法。

如何将 std::string 转换为 LPCSTR?

如何将文件系统路径转换为字符串

这似乎应该是非常基本的,但是到目前为止我尝试过的任何事情我都会收到关于转换为 LPCSTR 的错误或类似的东西C2228: left of '.c_str' must have class/struct/union让我感到困惑。

这是一个简单的例子:

// Assuming I have 
// std::filesystem::path path1 
// correctly set, I should be able to directly access it in
// a number of ways; i.e. path1.c_str(), path1.string.c_str(), etc.
// in order to pass it the function or a temp variable.
// However direct use of it in LoadLibrary() fails with the C2228 error.

HINSTANCE hGetProcIDDLL = LoadLibrary(path1.c_str());

我尝试避免使用宏并LoadLibraryA()直接调用,但没有运气。我还尝试了各种传递path1, path1.string(), path1.string.c_str()path1.wstring() 等的方法,但都没有成功。我还尝试以多种方式使用临时变量来避免在LoadLibrary().

LPCSTR temp_lpcstr = path1.c_str();  // Also tried things like path1.string() path1.string.c_str()

// Also tried just using a temp string...
std::string temp_string = path1.string(); // and variants.

我愿意尝试使用编码(如path1.u8string()等),但我认为直接使用 of 不应该是必要的LoadLibraryA()

我试图避免 C 强制转换并且更喜欢 c++ static_ 或 dynamic_ 但我会使用任何有效的东西。

任何帮助表示赞赏。

提前致谢。

UPDATE

@eryk-sun 的评论和 @Gulrak 的回答为我解决了这个问题。它看起来像我的设置,但path1.c_str()LoadLibrary wchar_t() 宏并没有按照它应该的方式将其引导到 LoadLibraryW() 。

注意:对于将来可能偶然发现此问题的任何其他人,这里是我的特定设置的更多详细信息。我正在使用 16.1.0 (~VS2019) 的 MSVC 编译器,但它是从 VSCode 和 CMake 调用的。我没有明确定义 _UNICODE,但是 VSCode 的智能感知肯定认为它已在某处定义并指向 LoadLibraryA()。但是,我认为编译器实际上并没有看到该定义,因此它解释path1.c_str()wchar_t.

4

2 回答 2

1

实际上,在 Windows 上,您应该能够LoadLibraryW(path1.c_str())像在 Windows 上一样使用 std::filesystem::path::c_str() 的返回类型,const wchar_t*因此它非常适合LoadLibraryW预期的LPCWSTR.

至于C2228我猜测的错误是,您path1.string.c_str()按照评论给出的尝试,应该是path1.string().c_str(). 这会给你一个LPCSTR兼容的字符串LoadLibaryA,但如果你的路径中有非ASCII的机会,我建议使用显式LoadLibaryW版本。

无论如何:在与 WinAPI 交互时,std::filesystem::path您应该使用显式的 A/W-Version 以使您的代码安全独立于 的状态_UNICODE,并且我总是建议使用这些*W版本。

于 2020-01-28T17:41:18.333 回答
1

您应该使用返回的类string的成员函数。然后调用返回的字符串。 pathstd::stringc_strstd::filesystem::path path /* = initialization here */; std::string str = path.string(); /* some handle = */ LoadLibrary(str.c_str());

于 2020-01-28T07:54:16.513 回答