如何将 std::filesystem::path 转换为 LPCSTR 以便在 LoadLibrary() 变体之一中使用?

How can I convert an std::filesystem::path to LPCSTR for use in one of the LoadLibrary() variants?

在 Windows 我正在尝试使用 LoadLibrary() 的变体之一来打开一个 dll 之前用 [=16= 写入 std::filesystem::path ].

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

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

How to convert std::string to 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() 等),但我认为直接使用 LoadLibraryA() 没有必要。

我试图避免 C 转换,更喜欢 C++ static_ 或 dynamic_,但我会使用任何有效的方法。

感谢任何帮助。

提前致谢。

UPDATE

@eryk-sun 的评论和@Gulrak 的回答为我解决了这个问题。 看起来在我的设置中,path1.c_str() 单独是 wchar_t,但 LoadLibrary() 宏没有拾取它并将其定向到 LoadLibraryW()。

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

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

实际上在 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()。这将为您提供 LoadLibaryALPCSTR 兼容字符串,但如果您的路径中有可能出现非 ASCII,我建议您使用明确的 LoadLibaryW 版本。

以任何方式:将 WinAPI 与 std::filesystem::path 连接时,您应该使用显式 A/W-Version 来使您的代码安全,而不受 _UNICODE 状态的影响,我总是建议 *W 版本。