Как я могу преобразовать std :: filesystem :: path в LPCSTR для использования в одном из вариантов LoadLibrary ()? - PullRequest
0 голосов
/ 28 января 2020

Вкл. Windows Я пытаюсь использовать один из вариантов LoadLibrary(), чтобы открыть dll, ранее записанный в std::filesystem::path с ofstream.

Примечание: я знаю, что dll написана правильно, так как я могу использовать ее стандартным способом, связываясь с ней во время выполнения.

Я пытался объединить методы из двух ответов ниже.

Как преобразовать std :: string в LPCSTR?

Как преобразовать путь файловой системы в строку

Это Похоже, что это должно быть довольно базовым c, но с любым, что я пробовал до сих пор, я либо получаю ошибку о преобразовании в 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 (), et c. без удачи Я также пытался использовать временную переменную несколькими способами, чтобы избежать приведения в 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() et c.) но я думаю, что это не должно быть необходимо с использованием LoadLibraryA() напрямую.

Я пытаюсь избежать C приведений и предпочел бы c ++ static_ или dynamic_, но я буду использовать все, что угодно это работает.

Любая помощь приветствуется.

Заранее спасибо.

UPDATE

@ комментарий eryk-sun и ответ @ Gulrak решили ее для меня. Похоже, что с моей установкой path1.c_str() - это wchar_t, но макрос LoadLibrary () не собирал это и не направлял его в LoadLibraryW (), как следует.

Примечание: Для всех, кто мог бы наткнуться на это в будущем, вот более подробная информация о моей спецификации c. Я использую компилятор MSV C из 16.1.0 (~ VS2019), но он вызывается из VSCode и CMake. Я не определяю явно _UNICODE, однако intellisense VSCode определенно считает, что он где-то определен, и указывает на LoadLibraryA (). Тем не менее, я думаю, что компилятор на самом деле не видит это определение, поэтому он интерпретирует path1.c_str() как wchar_t.

Ответы [ 2 ]

1 голос
/ 28 января 2020

На самом деле на 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-версию, чтобы сделать ваш код безопасным независимо от состояния _UNICODE, и я всегда предлагаю версии *W.

1 голос
/ 28 января 2020

Вы должны использовать string функцию-член класса path, которая возвращает std::string. Затем вызовите c_str для возвращенной строки. std::filesystem::path path /* = initialization here */; std::string str = path.string(); /* some handle = */ LoadLibrary(str.c_str());

...