Не удается исправить ошибку «неверный дескриптор» в WinAPI при попытке сделать что-либо, требующее его - PullRequest
1 голос
/ 08 мая 2019

Я пытаюсь поиграть с WinAPI, чтобы иметь возможность манипулировать консолью, в основном просто иметь возможность писать все, что я хочу, куда угодно, без необходимости переписывать всю консоль. Я помню, что однажды заставил его работать раньше, но это было давно, и я, кажется, потерял этот код ... упс.

Во всяком случае, я помню, что я преуспел с гораздо меньшими усилиями, чем сейчас.

Я использую эту страницу MS Docs для справки, и я помню, как использовал ее раньше, успешно.

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

#include <windows.h>
#include <iostream>

using namespace std;

int main()
{
    HANDLE hndl = GetStdHandle(STD_INPUT_HANDLE);
    if (hndl == INVALID_HANDLE_VALUE)
    {
        cout << "Invalid handle, error " << GetLastError();
        return 0;
    }
    long unsigned int *chars_written = new long unsigned int;
    if (!WriteConsoleOutputCharacter(hndl, "mystring", 8, {20, 30}, chars_written))
    {
        cout << "Could not write, error " << GetLastError();
        return 0;
    }
    return 0;
}

В результате появится окно консоли с сообщением «Не удалось записать, ошибка 6» и завершением приложения.

Ошибка 6 в соответствии с Коды системных ошибок - это «дескриптор недействителен».

Что я делаю не так? Я должен что-то упустить.

Кажется важным, чтобы я пытался работать в Code :: Blocks.

БОНУС: я попробовал MS Visual Studio с полным WinAPI SDK (некоторые важные части отсутствуют в Code :: Blocks), и, хотя основная проблема та же, функции в MS Visual Studio, похоже, не работают все соответствуют официальной ссылке, которую я использую, например WriteConsoleOutputCharacter требует LPCWSTR в качестве второго аргумента вместо LPCSTR, как упомянуто в источнике и работает в Code :: Blocks. Типы данных Windows

Редактировать: я обнаружил, что WriteConsoleOutputCharacter на самом деле является макросом и определяется по-разному между Code :: Blocks и MS Visual Studio, как две разные, существующие в обеих версиях функции: WriteConsoleOutputCharacterA () и WriteConsoleOutputCharacterW (), что, к сожалению, не упоминается в Документах MS.

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

1 Ответ

3 голосов
/ 08 мая 2019

Прежде всего WriteConsoleOutputCharacter() требуется широкая строка в качестве аргумента, в то время как вы передаете обычную строку "mystring" в качестве аргумента. Чтобы сделать его широким литералом, вы просто добавляете букву L в качестве префикса, например: L"mystring ". И программа выдает ошибку, потому что дескриптор, который вы получаете, является input handle (STD_INPUT_HANDLE). Между тем, если вы хотите вывести на консоль через дескриптор, вам нужно получить дескриптор output (STD_OUTPUT_HANDLE).

...