Хорошо, у меня есть проблема в моей программе. Я задавал вопрос об этом раньше, но никто не понимал мою проблему, поэтому на этот раз я пытаюсь по-новому взглянуть на нее.
Если вам интересно, это моя проблема:
Моя программа принимает аргументы в виде
char* argv[]
и я не могу сделать указатель на то, что наargv[1]
с помощьюLPWSTR
, поскольку это только указывает наconst wchar_t*
объекты.
Это новое, что я пытаюсь решить мою проблему (я пробовал несколько вещей, но мне нужно знать, как делать то, что я думаю, или, если это возможно)
По сути, моя идея состоит в том, чтобы #define
какая-то функция, которая принимает все, что на argv[1]
и определяет const wchar_t*
с этим значением.
Что-то вроде этого:
#define path ((const wchar_t*)argv[1])
Я не уверен, что это правильный способ (или даже если это возможно) сделать то, что я хочу сделать …
Если у вас нет лучшего способа решить мою проблему, пожалуйста (пожалуйста), скажите мне, как и помочь мне, я так долго думал об этом!
Объяснение моей программы:
Я делаю программу, которая получает аргументы. Аргументами являются имена дисков, например «F:». Затем он использует функцию
CreateFile
с буквой диска. Если вы идете Вот , и увидеть первый параметр функции, я думаю, вы поймете, что я имею в виду …. проблема в том, что для меня, чтобы сделать LPWSTR, мне нужен const wchat_t * объект …. я надеюсь, мой вопрос ясен на этот раз, в прошлый раз, люди действительно не поняли, что я пытался сделать.
Независимо, спасибо!
РЕДАКТИРОВАТЬ 1: вот строки решения моей программы (это то, как я должен сделать, чтобы она работала без аргументов) (здесь я использовал фиксированное значение)
int main()
{
HANDLE device;
device = CreateFile(L"\\\\.\\F:", // Drive to open
GENERIC_READ | GENERIC_WRITE, // Access mode
FILE_SHARE_READ | FILE_SHARE_WRITE, // Share Mode
NULL, // Security Descriptor
OPEN_EXISTING, // How to create
0, // File attributes
NULL);
}
Это с аргументами (не работает)
int main(int argc, char* argv[])
{
HANDLE device;
device = CreateFile(argv[1], // Drive to open
GENERIC_READ | GENERIC_WRITE, // Access mode
FILE_SHARE_READ | FILE_SHARE_WRITE, // Share Mode
NULL, // Security Descriptor
OPEN_EXISTING, // How to create
0, // File attributes
NULL); // Handle to template
}
^ это показывает, что я пытаюсь сделать
РЕДАКТИРОВАТЬ 2: я изменил CreateFile
в CreateFileA
и это коды eroor, которые он мне дает (диск D — это USB, это не жесткий диск)
Так что, если я не наберу неправильный способ набрать путь, это всегда дает мне ошибки. Я думаю, что попробуйте другой способ решить проблему, или, если кто-то знает, почему происходят эти ошибки, пожалуйста, сообщите!
РЕДАКТИРОВАТЬ 2: я изменил CreateFile на CreateFileA, и это коды eroor, которые он мне дает (диск D — это USB, а не жесткий диск)
Это совершенно другой вопрос, и не имеет ничего общего с wchar_t
,
В твоем первом прорезанном ты прошел "\\\\.\\F:"
(AKA \\.\F:
как только мы уберем С, спасаясь); во всех ваших попытках из командной строки вы никогда не указывали этот путь, но соответственно:
D
— поэтому он попытался открыть файл с именем D
в текущем каталоге, и он не нашел его (ошибка 2, ака ERROR_FILE_NOT_FOUND
);D:\
— корневой каталог, который нельзя открыть с помощью CreateFile
(ошибка 3, ака ERROR_PATH_NOT_FOUND
),D:
— текущий каталог на диске D :, который снова нельзя открыть с помощью CreateFile
(ошибка 5, ака ERROR_ACCESS_DENIED
);\D:
— файл с именем «D:» в корне текущего диска, который нельзя создать, если D:
неверное имя файла (ошибка 123, ака ERROR_INVALID_NAME
).Чтобы открыть диск как устройство, вы должен использовать \\.\X:
путь (где X
буква диска); Вы не можете просто выбросить все, что всплывает в уме, и надеяться, что это сработает. Вызов вашей программы из командной строки "\\.\D:"
и это будет работать нормально.
Конечно, если вы хотите, чтобы это было проще для пользователя, вы можете принять только букву диска в командной строке и написать код для создания строки, требуемой для CreateFile
основываясь на этом.
if(argc<1) {
printf("Not enough arguments\n");
return 1;
}
const char *drive = argv[1];
char d = drive[0];
// accept both `d` and `d:` as argument for the drive
if(!((d>='a' && d<='z') || (d>='A' && d<='Z')) ||
(drive[1]!=0 && drive[1]!=':') ||
drive[2]!=0) {
printf("Invalid drive specifier: `%s`\n", drive);
return 2;
}
char path[]="\\\\.\\X:";
path[4] = d;
// now you can use path as argument to CreateFileA
Далее следует оригинальный ответ, который все еще действует, но он решает совершенно другую проблему, не связанную с реальной проблемой, с которой сталкивается ОП
Вы не можете сделать LPWSTR
указать на char *
, особенно не жестоким приведением указателя — приведение указателя просто заставляет компилятор замолчать, это не меняет того факта, на что вы указываете не wchar_t
строка. Если вы хотите пройти char *
к функции, ожидающей wchar_t *
Вы должны выполнить фактическое преобразование указанных данных.
Теперь у вас есть несколько возможных решений:
_wmain
и получите аргументы командной строки непосредственно в виде широких символов;std::wstring
;CreateFile
это просто макрос, который расширяется до CreateFileA
или же CreateFileW
в зависимости от _UNICODE
макро). Итак, вы можете использовать CreateFileA
и передай свою строку как есть.Последние два решения не являются хорошими, потому что использование строк локальной кодировки в качестве аргументов командной строки не позволяет вашей программе открывать файлы с использованием произвольных символов Юникода. OTOH, используя wchar_t
почти везде это ужасно, так как они «заражают» практически каждый уголок обработки вашего приложения. Правильный (IMHO) выход — везде использовать UTF-8 и конвертировать на лету при общении с операционными системами; смотрите здесь для деталей.
Других решений пока нет …