Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of «de Finibus Bonorum et Malorum» (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, «Lorem ipsum dolor sit amet..», comes from a line in section 1.10.32.
Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of «de Finibus Bonorum et Malorum» (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, «Lorem ipsum dolor sit amet..», comes from a line in section 1.10.32.
Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of «de Finibus Bonorum et Malorum» (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, «Lorem ipsum dolor sit amet..», comes from a line in section 1.10.32.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
#include "Main.h" int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, char* lpCmdLine, LPCTSTR nCmdShow, LPSTR WindowName, int WindowWidth, int WindowHeight) { g_hInstance = GetModuleHandle(NULL); WNDCLASSEX wc; wc.cbSize = sizeof(WNDCLASSEX); //Размер структуры wc.style = CS_HREDRAW | CS_VREDRAW; //Стили класса окна wc.lpfnWndProc = WndProc; //Функция обработки сообщений wc.cbClsExtra = 0; //Количество выделяемой памяти при создании приложения wc.cbWndExtra = 0; //Количество выделяемой памяти при создании приложения wc.hInstance = g_hInstance; //Дескриптор приложения wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); //Загружаем стандартную иконку wc.hCursor = LoadCursor(0, IDC_ARROW); //Загружаем стандартный курсор wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);//Окно будет закрашено в белый цвет wc.lpszMenuName = 0; //Не используем меню wc.lpszClassName = "Lost Days"; //Названия класса wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); //Загружаем стандартную иконку if (!RegisterClassEx(&wc)) //Регистрируем класс в Windows { Shutdown(); //Освобождаем память MessageBox(NULL, "Can`t register window class", "Error", MB_OK | MB_ICONERROR); //Выводим сообщение return 0; //Завершаем работу приложения } g_hWnd = CreateWindowEx( //Создаем окно WS_EX_APPWINDOW | WS_EX_WINDOWEDGE, //Расширенный стиль окна "Lost Days", //Названия класса окна WindowName, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,//Стиль окна 0, //Позиция окна по оси Х 0, //Позиция окна по оси У WindowWidth, //Ширина окна WindowHeight, //Высота окна NULL, //Это наше главное окно NULL, //Нету меню g_hInstance, //Дескриптор приложения NULL); //Дополнительный настроек не используем if (g_hWnd == NULL) //Если не создали окно { Shutdown(); MessageBox(NULL, "Can`t create window", "Error", MB_OK | MB_ICONERROR);//Выводим сообщение return 0; //Завершаем работу приложения } if (!InitDirect3D(D3DFMT_R5G6B5, D3DFMT_D16, WindowWidth, WindowHeight)) //Если не смогли инициализировать Direct3D { Shutdown(); MessageBox(NULL, "Can`t create direct3d", "Error", MB_OK | MB_ICONERROR);//Выводим сообщение return 0; //Завершаем работу приложения } ShowWindow(g_hWnd, SW_SHOW); //Отображаем окно UpdateWindow(g_hWnd); //Обновляем окно SetFocus(g_hWnd); //Устанавливаем фокус на наше окно SetForegroundWindow(g_hWnd); //Устанавливаем приоритет окна выше среднего MSG msg; ZeroMemory(&msg, sizeof(msg)); while (g_bApplicationState) //Начинаем бесконечный цикл обработки сообщений { if (PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE))//Получаем сообщения { TranslateMessage(&msg); //Обрабатываем сообщения DispatchMessage(&msg); //Обрабатываем сообщения } else DrawFrame(); //Если сообщений нету рисуем кадры } Shutdown(); //Освобождаем память return 0; //Завершаем работу приложения } |
-
Question
-
I am trying to mutilate a Microsoft/GitHub code and adjust it to my particular needs in a C++ application. As a part of my «game» I need to activate a PipeServer. I chose
Named Pipe Server Using Overlapped I/O. I envision my task as creating a monoplex client-server combination with a possibility of using 2-3 clients in the future with one server. It should be a byte system, not the message one. so I created a class NewMultiClientPipeServer
where I copied the server code as presented at the link I posted. In the same cpp file I wrote another class:class DoWork { public: void DoWorkW (void) { int bb; DoWork(); // constructor NewMultiClientPipeServer * newServ = new NewMultiClientPipeServer(); bb = newServ->_tmain(); std::cout << bb; } } NewWork;
My intention is to activate this Server by calling _tmain from winmain.cpp. Here is the place I think will be appropriate:
INT WINAPI wWinMain(HINSTANCE,HINSTANCE,LPWSTR,INT) { if (!GetConsole()) MessageBox(NULL, TEXT("Could not obtain console"), TEXT("GetConsole() failed"), MB_OK); int x = 42; // variable for printf printf("Value of x is %dn", x); // CALLING SEQUENCE HERE?? HWND hwnd = 0;
Nothing I tried so far worked for me. I need help.
Thanks, — MyCatAlex
-
Moved by
Thursday, February 27, 2020 3:11 AM
-
Moved by
Answers
-
I don’t know what you’re trying to do with the DoWork class. The _tmain function is an infinite loop, so it’s going to need to be in a thread. It’s pretty independent.
NewMultiClientPipeServer server;
std::thread( &NewMultiClientPipeServer::_tmain, &server ).detach();You might think about changing the name _tmain to something more descriptive, like ServerForever or something.
Tim Roberts | Driver MVP Emeritus | Providenza & Boekelheide, Inc.
-
Marked as answer by
MyCatAlex
Wednesday, February 26, 2020 8:49 PM -
Unmarked as answer by
MyCatAlex
Thursday, February 27, 2020 1:12 AM -
Marked as answer by
MyCatAlex
Friday, February 28, 2020 4:51 PM
-
Marked as answer by
-
OK then, continuing on with MFCaptureD3D —
I took the MS Named piper server sample and broke it into two files —
pipeserver.h
#pragma once #include <windows.h> #include <stdio.h> #include <tchar.h> #include <strsafe.h> #include <process.h> // Added by RLWA32 #define CONNECTING_STATE 0 #define READING_STATE 1 #define WRITING_STATE 2 #define INSTANCES 4 #define PIPE_TIMEOUT 5000 #define BUFSIZE 4096 typedef struct { OVERLAPPED oOverlap; HANDLE hPipeInst; TCHAR chRequest[BUFSIZE]; DWORD cbRead; TCHAR chReply[BUFSIZE]; DWORD cbToWrite; DWORD dwState; BOOL fPendingIO; } PIPEINST, *LPPIPEINST; VOID DisconnectAndReconnect(DWORD); BOOL ConnectToNewClient(HANDLE, LPOVERLAPPED); VOID GetAnswerToRequest(LPPIPEINST); UINT __stdcall PipeSrvThread(LPVOID pv); // Added by RLWA32
pipeserver.cpp
#include "pipeserver.h" PIPEINST Pipe[INSTANCES]; HANDLE hEvents[INSTANCES]; UINT __stdcall PipeSrvThread(LPVOID /*pv*/) { DWORD i, dwWait, cbRet, dwErr; BOOL fSuccess; LPTSTR lpszPipename = TEXT("\\.\pipe\mynamedpipe"); // The initial loop creates several instances of a named pipe // along with an event object for each instance. An // overlapped ConnectNamedPipe operation is started for // each instance. for (i = 0; i < INSTANCES; i++) { // Create an event object for this instance. hEvents[i] = CreateEvent( NULL, // default security attribute TRUE, // manual-reset event TRUE, // initial state = signaled NULL); // unnamed event object if (hEvents[i] == NULL) { printf("CreateEvent failed with %d.n", GetLastError()); return 0; } Pipe[i].oOverlap.hEvent = hEvents[i]; Pipe[i].hPipeInst = CreateNamedPipe( lpszPipename, // pipe name PIPE_ACCESS_DUPLEX | // read/write access FILE_FLAG_OVERLAPPED, // overlapped mode PIPE_TYPE_MESSAGE | // message-type pipe PIPE_READMODE_MESSAGE | // message-read mode PIPE_WAIT, // blocking mode INSTANCES, // number of instances BUFSIZE * sizeof(TCHAR), // output buffer size BUFSIZE * sizeof(TCHAR), // input buffer size PIPE_TIMEOUT, // client time-out NULL); // default security attributes if (Pipe[i].hPipeInst == INVALID_HANDLE_VALUE) { printf("CreateNamedPipe failed with %d.n", GetLastError()); return 0; } // Call the subroutine to connect to the new client Pipe[i].fPendingIO = ConnectToNewClient( Pipe[i].hPipeInst, &Pipe[i].oOverlap); Pipe[i].dwState = Pipe[i].fPendingIO ? CONNECTING_STATE : // still connecting READING_STATE; // ready to read } while (1) { // Wait for the event object to be signaled, indicating // completion of an overlapped read, write, or // connect operation. dwWait = WaitForMultipleObjects( INSTANCES, // number of event objects hEvents, // array of event objects FALSE, // does not wait for all INFINITE); // waits indefinitely // dwWait shows which pipe completed the operation. i = dwWait - WAIT_OBJECT_0; // determines which pipe if (i < 0 || i >(INSTANCES - 1)) { printf("Index out of range.n"); return 0; } // Get the result if the operation was pending. if (Pipe[i].fPendingIO) { fSuccess = GetOverlappedResult( Pipe[i].hPipeInst, // handle to pipe &Pipe[i].oOverlap, // OVERLAPPED structure &cbRet, // bytes transferred FALSE); // do not wait switch (Pipe[i].dwState) { // Pending connect operation case CONNECTING_STATE: if (!fSuccess) { printf("Error %d.n", GetLastError()); return 0; } Pipe[i].dwState = READING_STATE; break; // Pending read operation case READING_STATE: if (!fSuccess || cbRet == 0) { DisconnectAndReconnect(i); continue; } Pipe[i].cbRead = cbRet; Pipe[i].dwState = WRITING_STATE; break; // Pending write operation case WRITING_STATE: if (!fSuccess || cbRet != Pipe[i].cbToWrite) { DisconnectAndReconnect(i); continue; } Pipe[i].dwState = READING_STATE; break; default: { printf("Invalid pipe state.n"); return 0; } } } // The pipe state determines which operation to do next. switch (Pipe[i].dwState) { // READING_STATE: // The pipe instance is connected to the client // and is ready to read a request from the client. case READING_STATE: fSuccess = ReadFile( Pipe[i].hPipeInst, Pipe[i].chRequest, BUFSIZE * sizeof(TCHAR), &Pipe[i].cbRead, &Pipe[i].oOverlap); // The read operation completed successfully. if (fSuccess && Pipe[i].cbRead != 0) { Pipe[i].fPendingIO = FALSE; Pipe[i].dwState = WRITING_STATE; continue; } // The read operation is still pending. dwErr = GetLastError(); if (!fSuccess && (dwErr == ERROR_IO_PENDING)) { Pipe[i].fPendingIO = TRUE; continue; } // An error occurred; disconnect from the client. DisconnectAndReconnect(i); break; // WRITING_STATE: // The request was successfully read from the client. // Get the reply data and write it to the client. case WRITING_STATE: GetAnswerToRequest(&Pipe[i]); fSuccess = WriteFile( Pipe[i].hPipeInst, Pipe[i].chReply, Pipe[i].cbToWrite, &cbRet, &Pipe[i].oOverlap); // The write operation completed successfully. if (fSuccess && cbRet == Pipe[i].cbToWrite) { Pipe[i].fPendingIO = FALSE; Pipe[i].dwState = READING_STATE; continue; } // The write operation is still pending. dwErr = GetLastError(); if (!fSuccess && (dwErr == ERROR_IO_PENDING)) { Pipe[i].fPendingIO = TRUE; continue; } // An error occurred; disconnect from the client. DisconnectAndReconnect(i); break; default: { printf("Invalid pipe state.n"); return 0; } } } return 0; } // DisconnectAndReconnect(DWORD) // This function is called when an error occurs or when the client // closes its handle to the pipe. Disconnect from this client, then // call ConnectNamedPipe to wait for another client to connect. VOID DisconnectAndReconnect(DWORD i) { // Disconnect the pipe instance. if (!DisconnectNamedPipe(Pipe[i].hPipeInst)) { printf("DisconnectNamedPipe failed with %d.n", GetLastError()); } // Call a subroutine to connect to the new client. Pipe[i].fPendingIO = ConnectToNewClient( Pipe[i].hPipeInst, &Pipe[i].oOverlap); Pipe[i].dwState = Pipe[i].fPendingIO ? CONNECTING_STATE : // still connecting READING_STATE; // ready to read } // ConnectToNewClient(HANDLE, LPOVERLAPPED) // This function is called to start an overlapped connect operation. // It returns TRUE if an operation is pending or FALSE if the // connection has been completed. BOOL ConnectToNewClient(HANDLE hPipe, LPOVERLAPPED lpo) { BOOL fConnected, fPendingIO = FALSE; // Start an overlapped connection for this pipe instance. fConnected = ConnectNamedPipe(hPipe, lpo); // Overlapped ConnectNamedPipe should return zero. if (fConnected) { printf("ConnectNamedPipe failed with %d.n", GetLastError()); return 0; } switch (GetLastError()) { // The overlapped connection in progress. case ERROR_IO_PENDING: fPendingIO = TRUE; break; // Client is already connected, so signal an event. case ERROR_PIPE_CONNECTED: if (SetEvent(lpo->hEvent)) break; // If an error occurs during the connect operation... default: { printf("ConnectNamedPipe failed with %d.n", GetLastError()); return 0; } } return fPendingIO; } VOID GetAnswerToRequest(LPPIPEINST pipe) { _tprintf(TEXT("[%p] %sn"), pipe->hPipeInst, pipe->chRequest); StringCchCopy(pipe->chReply, BUFSIZE, TEXT("Default answer from server")); pipe->cbToWrite = (lstrlen(pipe->chReply) + 1) * sizeof(TCHAR); }
Add these pipeserver.h and pipeserver.cpp to the MFCaptureD3D project.
In winmain.cpp add the include for pipeserver.h at the top of the file —
#include "MFCaptureD3D.h" #include "resource.h" #include <stdio.h> #include "pipeserver.h"
Add the following in winmain.cpp after the console has been created, for example —
if (!GetConsole()) MessageBox(NULL, TEXT("Could not obtain console"), TEXT("GetConsole() failed"), MB_OK); int x = 42; // variable for printf printf("Value of x is %dn", x); printf("Starting Pipe Server threadn"); UINT threadid = 0; HANDLE hPipeSrvThread = (HANDLE)_beginthreadex(nullptr, 0, PipeSrvThread, nullptr, 0, &threadid); if (hPipeSrvThread) { printf("Pipe Server thread id is %un", threadid); CloseHandle(hPipeSrvThread); } else { ULONG err = 0; _get_doserrno(&err); printf("Creation of pipe server thread failed, error code was %dn", err); }
Now you can run the pipe client sample and see the results on the console.
-
Marked as answer by
MyCatAlex
Friday, February 28, 2020 4:51 PM
-
Marked as answer by
-
-
Marked as answer by
MyCatAlex
Friday, February 28, 2020 7:27 PM
-
Marked as answer by
-
OK, some new information.
I discovered to me regret, that I missed one of your suggestions. I did not place this code in winmain.cpp
if (!GetConsole()) MessageBox(NULL, TEXT("Could not obtain console"), TEXT("GetConsole() failed"), MB_OK); int x = 42; // variable for printf printf("Value of x is %dn", x); printf("Starting Pipe Server threadn"); UINT threadid = 0; HANDLE hPipeSrvThread = (HANDLE)_beginthreadex(nullptr, 0, PipeSrvThread, nullptr, 0, &threadid); if (hPipeSrvThread) { printf("Pipe Server thread id is %un", threadid); CloseHandle(hPipeSrvThread); } else { ULONG err = 0; _get_doserrno(&err); printf("Creation of pipe server thread failed, error code was %dn", err); }
although I included the header files you recommended, they are there.
When I tried to compile it with /std:c++14 it gave me 12 errors, all of them in your code that I just added to winmain.cpp.
I have a difficult time believing that up to this point you have followed all of the instructions that I have given.
Have you included any code in the MFCaptureD3D files other than code that I have given to yOU?
Show me the errors that you say are attributable to my code.
-
Edited by
RLWA32
Saturday, February 29, 2020 8:33 PM -
Marked as answer by
MyCatAlex
Sunday, March 1, 2020 5:01 PM
-
Edited by
-
Why did you comment out the GetConsole() function that I provided?
And the other code was supposed to be placed in the wWinmain function as you were instructed in other posts in the thread where I first instructed you on how to create a console.
So you didn’t follow my instructions after all.
INT WINAPI wWinMain(HINSTANCE,HINSTANCE,LPWSTR,INT) { HWND hwnd = 0; if (!GetConsole()) MessageBox(NULL, TEXT("Could not obtain console"), TEXT("GetConsole() failed"), MB_OK); int x = 42; // variable for printf printf("Value of x is %dn", x); printf("Starting Pipe Server threadn"); UINT threadid = 0; HANDLE hPipeSrvThread = (HANDLE)_beginthreadex(nullptr, 0, PipeSrvThread, nullptr, 0, &threadid); if (hPipeSrvThread) { printf("Pipe Server thread id is %un", threadid); CloseHandle(hPipeSrvThread); } else { ULONG err = 0; _get_doserrno(&err); printf("Creation of pipe server thread failed, error code was %dn", err); } (void)HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0); if (InitializeApplication() && InitializeWindow(&hwnd)) { MessageLoop(hwnd); } CleanUp(); return 0; }
-
Edited by
RLWA32
Saturday, February 29, 2020 10:31 PM -
Marked as answer by
MyCatAlex
Sunday, March 1, 2020 5:01 PM
-
Edited by
-
Did you fix the wWinMain function as I previously illustrated to show the proper placement of the code?
You’re making this much more difficult than it has to be.
-
Edited by
RLWA32
Saturday, February 29, 2020 11:24 PM -
Marked as answer by
MyCatAlex
Sunday, March 1, 2020 5:00 PM
-
Edited by
-
Its good to hear that you got it sorted out.
Yes, you did share a bit about your background in a previous post. I had taken a look at the Wikipedia content — its beyond my understanding.
And I’ll be happy to help you again with your future questions.
-
Marked as answer by
MyCatAlex
Sunday, March 1, 2020 5:00 PM
-
Marked as answer by
-
The pipe server code is virtually the same as provided in the MS sample at
https://docs.microsoft.com/en-us/windows/win32/ipc/named-pipe-server-using-overlapped-i-oSince the sample code was posted as a complete console application I broke it into a header file and a .cpp file. I added two lines to the header file, an include for process.h and a function declaration for the pipe server threadproc (PipeSvrvThread).
The body of the sample’s _tmain() function was used in PipeSrvThread. If I remember correctly, I made one small change to a function in the sample to eliminate a C4477 warning error.Original sample code — %d used in _tprintf
VOID GetAnswerToRequest(LPPIPEINST pipe) { _tprintf( TEXT("[%d] %sn"), pipe->hPipeInst, pipe->chRequest); StringCchCopy( pipe->chReply, BUFSIZE, TEXT("Default answer from server") ); pipe->cbToWrite = (lstrlen(pipe->chReply)+1)*sizeof(TCHAR); }
Revised sample code — %p used in _tprintf
VOID GetAnswerToRequest(LPPIPEINST pipe) { _tprintf(TEXT("[%p] %sn"), pipe->hPipeInst, pipe->chRequest); StringCchCopy(pipe->chReply, BUFSIZE, TEXT("Default answer from server")); pipe->cbToWrite = (lstrlen(pipe->chReply) + 1) * sizeof(TCHAR); }
The MS pipe server code is a message based. It can be used as-is with the MS named pipe client sample at
https://docs.microsoft.com/en-us/windows/win32/ipc/named-pipe-client-
Marked as answer by
MyCatAlex
Monday, March 2, 2020 3:18 PM
-
Marked as answer by
-
Please understand that all I have done is grafted a code from one MS sample into another one.
I am not recommending any particular pipe server. In fact, you determined the pipe server in the initial post where you said, «As a part of my «game» I need to activate a PipeServer. I chose
Named Pipe Server Using Overlapped I/O.»
That sample code runs the pipe server in an infinite loop. Consequently, a separate thread had to be used to prevent the pipe server from making the UI thread of the MFCaptureD3D sample unresponsive. While the infinite loop was acceptable for
a sample that illustrated concepts, it may or may not be suitable for your particular needs, whatever they might be.I’m not familiar how the MFCaptureD3D sample code works. Nor do I understand exactly what you are trying to do. As I indicated previously, pipes are for inter-process communication. Yet you said above «The second question is
how I can start transferring byte values from device.cpp of MFCaptureD3D project (TransformImage_NV12 function) to another file which I haven’t created yet. That file will collect images one by one and do Fourier analysis
of the pictures.»Why do you need pipes if you’re going to write data to a file? Its all very confusing to me.
Perhaps if you stepped back from the coding details and gave me a higher level overview I could be more helpful.
-
Edited by
RLWA32
Monday, March 2, 2020 11:13 PM -
Marked as answer by
MyCatAlex
Tuesday, March 3, 2020 2:36 AM
-
Edited by
Добавлено 27 марта 2021 в 12:55
В этом разделе мы рассмотрим некоторые из распространенных проблем, с которыми, похоже, начинающие программисты сталкиваются с довольно высокой вероятностью. Это не исчерпывающий список проблем компиляции или запуска программ, а скорее прагматичный список решений самых основных проблем. Если у вас есть предложения по другим вопросам, которые могут быть добавлены в этот список, опубликуйте их в разделе комментариев ниже.
Общие проблемы во время выполнения
Вопрос: При выполнении программы окно консоли мигает, а затем сразу закрывается.
Сначала добавьте или убедитесь, что следующие строки находятся в верхней части вашей программы (пользователи Visual Studio должны убедиться, что эти строки появляются после #include "pch.h"
или #include "stdafx.h"
, если таковые существуют):
#include <iostream>
#include <limits>
Во-вторых, добавьте следующий код в конец функции main()
(прямо перед оператором return
):
// сбрасываем все флаги ошибок
std::cin.clear();
// игнорируем любые символы во входном буфере, пока не найдем новую строку
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), 'n');
// получаем от пользователя еще один символ
std::cin.get();
Это заставит вашу программу ждать, пока пользователь нажмет любую клавишу, прежде чем продолжить, что даст вам время изучить вывод вашей программы, прежде чем ваша операционная система закроет окно консоли.
Другие решения, такие как обычно предлагаемое system("pause")
, могут работать только в определенных операционных системах, и их следует избегать.
Более старые версии Visual Studio могут не приостанавливаться, когда программа запускается в режиме Начать с отладкой (Start With Debugging) (F5). Попробуйте запустить в режиме Начать без отладки (Start Without Debugging) (Ctrl + F5).
Вопрос: Я запустил свою программу, получил окно, но ничего не выводится.
Выполнение может блокировать ваш антивирус. Попробуйте временно отключить его и посмотрите, не в этом ли проблема.
Вопрос: Моя программа компилируется, но работает некорректно. Что не так?
Отладьте ее! Советы по диагностике и отладке программ приведены далее в главе 3.
Общие проблемы времени компиляции
Вопрос: Когда я компилирую свою программу, я получаю ошибку о неразрешенном внешнем символе _main
или _WinMain@16
Это означает, что ваш компилятор не может найти вашу функцию main()
. А все программы должны включать в себя эту функцию.
Есть несколько вещей, которые нужно проверить:
- Содержит ли ваш код функцию с именем
main
? - Правильно ли написано имя
main
? - Когда вы компилируете свою программу, видите ли вы, что файл, содержащий функцию
main()
, компилируется? Если нет, либо переместите функциюmain()
в другой файл, либо добавьте этот файл в свой проект (для получения дополнительной информации о том, как это сделать, смотрите урок «2.7 – Программы с несколькими файлами кода»). - Вы точно создали консольный проект? Попробуйте создать новый консольный проект.
Вопрос: Я пытаюсь использовать функциональность C++11/14/17/XX, но она не работает.
Если у вас старый компилятор, он может не поддерживать эти более свежие дополнения к языку. В этом случае обновите свой компилятор.
В случае с современными IDE/компиляторами ваш компилятор может по умолчанию использовать более старый стандарт языка. Мы рассмотрим, как изменить стандарт языка в уроке «0.12 – Настройка компилятора: выбор стандарта языка».
Вопрос: При попытке использовать cin
, cout
или endl
компилятор говорит, что cin
, cout
или endl
являются «необъявленными идентификаторами».
Во-первых, убедитесь, что вы включили следующую строку в верхней части файла:
#include <iostream>
Во-вторых, убедитесь, что каждое использование cin
, cout
и end
l имеет префикс «std::
«. Например:
std::cout << "Hello world!" << std::endl;
Если это не решит вашу проблему, возможно, ваш компилятор устарел или установка повреждена. Попробуйте переустановить и/или обновить компилятор до последней версии.
Вопрос: При попытке использовать endl
для завершения напечатанной строки компилятор говорит, что end1
является «необъявленным идентификатором».
Убедитесь, что вы не перепутали букву l (нижний регистр L) в endl
с цифрой 1. endl
– это все буквы. Убедитесь, что ваш редактор использует шрифт, который проясняет разницу между строчной буквой L, заглавной i и цифрой 1. Кроме того, во многих шрифтах, не предназначенных для программирования, можно легко перепутать заглавную букву o и цифру ноль.
Проблемы с Visual Studio
Вопрос: При компиляции с помощью Microsoft Visual C++ вы получаете фатальную ошибку C1010 с сообщением типа «c:vcprojectstest.cpp(263) :fatal error C1010: unexpected end of file while looking for precompiled header directive» (неожиданный конец файла при поиске директивы предварительно скомпилированного заголовка).
Эта ошибка возникает, когда компилятор Microsoft Visual C++ настроен на использование предварительно скомпилированных заголовков, но один (или несколько) ваших файлов кода C++ не включает #include "stdafx.h"
или #include "pch.h"
в качестве первой строки кода файла.
Предлагаемое нами решение – отключить предварительно скомпилированные заголовки, как это сделано в уроке «0.7 – Компиляция вашей первой программы».
Если вы хотите, чтобы предварительно скомпилированные заголовки были включены, чтобы решить эту проблему, просто найдите файл(ы), вызывающий ошибку (в приведенной выше ошибке виновником является test.cpp), и добавьте следующую строку в самом верху файла):
#include "pch.h"
В более старых версиях Visual Studio используется stdafx.h вместо pch.h, поэтому, если pch.h не решает проблему, попробуйте stdafx.h.
Обратите внимание, что для программ с несколькими файлами каждый файл кода C++ должен начинаться с этой строки.
Кроме того, вы можете отключить предварительно скомпилированные заголовки.
Вопрос: Visual Studio выдает следующую ошибку: «1MSVCRTD.lib(exe_winmain.obj) : error LNK2019: unresolved external symbol _WinMain@16 referenced in function «int __cdecl invoke_main(void)» (?invoke_main@@YAHXZ)» (неразрешенный внешний символ _WinMain@16).
Скорее всего, вы создали не консольное приложение, а графическое приложение Windows. Создайте заново свой проект и убедитесь, что вы создали его как консольный проект Windows (или Win32).
Вопрос: Когда я компилирую свою программу, я получаю предупреждение «Cannot find or open the PDB file» (не могу найти или открыть файл PDB).
Это предупреждение, а не ошибка, поэтому оно не должно повлиять на вашу программу. Однако она раздражает. Чтобы исправить это, перейдите в меню Debug (Отладка) → Options and Settings (Параметры) → Symbols (Символы) и установите флажок Microsoft Symbol Server (Сервер символов Microsoft).
Прочее
Вопрос: У меня есть еще одна проблема, которую я не могу понять. Как я могу быстро получить ответ?
По мере обучения у вас, несомненно, будут возникать вопросы или неожиданные проблемы. Что делать дальше, зависит от вашей проблемы. Но в целом есть несколько вещей, которые вы можете попробовать.
Сначала спросите Google. Найдите хороший способ сформулировать свой вопрос и выполните поиск в Google. Если вы получили сообщение об ошибке, вставьте точное сообщение в Google, используя кавычки. Скорее всего, кто-то уже задавал тот же вопрос, и вы найдете ответ.
Если это не поможет, спросите на сайте вопросов и ответов. Существуют веб-сайты, предназначенные для вопросов и ответов о программировании, например, Stack Overflow. Попробуйте разместить там свой вопрос. Не забудьте подробно описать, в чем заключается ваша проблема, и включить всю необходимую информацию, например, какую ОС и какую IDE вы используете.
Теги
C++ / CppFAQLearnCppДля начинающихОбучениеПрограммирование