如何将 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_str
。
std::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()
。这将为您提供 LoadLibaryA
的 LPCSTR
兼容字符串,但如果您的路径中有可能出现非 ASCII,我建议您使用明确的 LoadLibaryW
版本。
以任何方式:将 WinAPI 与 std::filesystem::path
连接时,您应该使用显式 A/W-Version 来使您的代码安全,而不受 _UNICODE
状态的影响,我总是建议 *W
版本。
在 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_str
。
std::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()
。这将为您提供 LoadLibaryA
的 LPCSTR
兼容字符串,但如果您的路径中有可能出现非 ASCII,我建议您使用明确的 LoadLibaryW
版本。
以任何方式:将 WinAPI 与 std::filesystem::path
连接时,您应该使用显式 A/W-Version 来使您的代码安全,而不受 _UNICODE
状态的影响,我总是建议 *W
版本。