在Windows上,我正在尝试使用LoadLibrary()
的变体之一来打开先前写入带有ofstream
std::filesystem::path
的dll
。
注意:我知道 dll 编写正确,因为我可以通过在运行时链接到它以标准方式使用它。
我一直在尝试结合以下两个答案的方法。
如何将标准::字符串转换为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(( 等,但没有运气。 我还尝试以多种方式使用 temp 变量来避免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
。
实际上在Windows上你应该能够使用LoadLibraryW(path1.c_str())
因为在Windows上返回的std::filesystem::p ath::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版本来使您的代码独立于_UNICODE
状态的安全,我建议使用*W
版本。
你应该使用path
类的成员函数string
它返回std::string
。然后对返回的字符串调用c_str
。std::filesystem::path path /* = initialization here */;
std::string str = path.string();
/* some handle = */ LoadLibrary(str.c_str());