Консультация № 181615
26.12.2010, 02:55
0.00 руб.
0 8 1
Здравствуйте, уважаемые эксперты! Прошу ответить начинающему на следующий вопрос:
Начал изучать С++ по материалам одного сайта, где среди прочего описан процесс компиляции первой простенькой программы MessageBox на Visual Studio 2005. У меня не получается получить .exe файл. Не знаю, то ли исходник неправилен, то ли VS 2005 неправильно установилась, то ли я такой. Пишется:
source1.cpp(5) : error C2664: 'MessageBoxW' : cannot convert parameter 2 from 'const char [18]' to 'LPCWSTR'
Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
А. Делаю в VS 2005, как написано на сайте:
1. Создаю новый пустой проект: File->New->Project,
появляется окно New Project, в котором выбираю: Visual C++->Win32 Project.
В окне Application Setting выбираю Windows application и Empty project.
2. Создаю новый файл С++
File->New->File, в окне New File выбираю Visual C++, потом С++File(.cpp), далее Open
3. Сохраняю файл:
File->Save Source1.cpp
4. Добавляю файл к проекту:
Project->Add Existing Item
5. Ввожу скопированный текст в файл Source1.cpp
6. Нажимаю F7 (Build Solution)
7. Получаю ошибку.

Б. Пытаюсь скомпилировать в Borland C++ Builder Enterprise v6, тоже не получается, но ошибка уже другая: (C++ Warning) File1.cpp(6): W8070 Function should return a value
Делаю так:
1. Удаляю появившиеся при запуске Form1 и Unit1.cpp без сохранения
2. Создаю новый файл: File->New->Other->Cpp File
3. Ввожу скопированный текст в файл File1.cpp
4. Сохраняю файл: File->Save File1.cpp
5. Нажимаю Run (F7)

До создания нового файла предварительно сделал:
в меню Project -> Options -> Packages убрал флаг в Build with runtime packages;
Project -> Options -> Linker убрал флаг в Use dynamic RTL
Project -> Options -> Compiler нажал на Release
Пробовал менять соглашение о вызове, но безрезультатно:
Project->Options->Advanced Compiler в Calling conversion: с С менял на Standart call (т.к. WinAPI использует stdcall).
Как правильно компилировать написанные на С++ программы с WinAPI в VS 2005 и Borland C++ Builder Enterprise v6.


Приложение:
#include<windows.h>

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
{
MessageBox(0, "Привет, Win32 API", "Первое окно...", MB_ICONINFORMATION|MB_OK);
}

Обсуждение

Неизвестный
26.12.2010, 03:04
общий
По поводу ошибки в VS, поставьте в свойствах проекта Use multibyte character set, или задайте константы через макрос _L("строка").
давно
Старший Модератор
312929
1973
26.12.2010, 04:40
общий
В CBuilder у Вас не ошибка, а предупреждение ("Функция должна возвращать значение"). Это не страшно, но все же добавьте в конце (после MessageBox) return 0.
Неизвестный
26.12.2010, 05:39
общий
это ответ
Здравствуйте, Adsorores!

Вы объявляете ф-цию как int WINAPI WinMain()....
тогда в конце нужно дописать return 0

или измените void WINAPI WinMain()... и в конце ничего дописывать ненужно

Приложение:
#include<windows.h>

void WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
{
MessageBox(0, "Привет, Win32 API", "Первое окно...", MB_ICONINFORMATION|MB_OK);
}
5
Спасибо за ответы!
Неизвестный
26.12.2010, 11:10
общий
"Вы объявляете ф-цию как int WINAPI WinMain()....тогда в конце нужно дописать return 0"
Переделал, дописав return 0; :
#include<windows.h>

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
{
MessageBox(0, "Привет, Win32 API", "Первое окно...", MB_ICONINFORMATION|MB_OK);
return 0;
}
Ошибка после нажатия на F7:
source1.cpp(5) : error C2664: 'MessageBoxW' : cannot convert parameter 2 from 'const char [18]' to 'LPCWSTR'
Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

"или измените void WINAPI WinMain()... и в конце ничего дописывать не нужно"
Написал так:
#include<windows.h>

void WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
{
MessageBox(0, "Привет, Win32 API", "Первое окно...", MB_ICONINFORMATION|MB_OK);
}
Получил ошибки:
source1.cpp(4) : error C2556: 'void WinMain(HINSTANCE,HINSTANCE,LPSTR,int)' : overloaded function differs only by return type from 'int WinMain(HINSTANCE,HINSTANCE,LPSTR,int)'
f:\visual studio 2005 professional\vc\platformsdk\include\winbase.h(1875) : see declaration of 'WinMain'
source1.cpp(4) : error C2371: 'WinMain' : redefinition; different basic types
f:\visual studio 2005 professional\vc\platformsdk\include\winbase.h(1875) : see declaration of 'WinMain'
source1.cpp(5) : error C2664: 'MessageBoxW' : cannot convert parameter 2 from 'const char [18]' to 'LPCWSTR'
Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

Совет Verena поставить в свойствах проекта Use multibyte character set мне помог, хотя в самой своей программе я ничего не менял.
Но мне интересно, почему Ваши советы не помогли.
Неизвестный
26.12.2010, 11:12
общий
Адресаты:
В CBuilder с return 0; создаётся Project1.exe, но не запускается. А в VS и создаётся, и запускается. Не знаете, как правильно запустить файл?
Неизвестный
26.12.2010, 12:08
общий
Но мне интересно, почему Ваши советы не помогли

На самом деле существуют две функции MessageBox, которые называются MessageBoxA и MessageBoxW. Первая в качестве строковых агрументов принимает обычные строки, а вторая - юникодные строки (с префиксом L). Когда вы пишите просто MessageBox, то в зависимости от опций проекта будет подставлена первая или вторая функция. Явные вызовы должны выглядеть так:
MessageBoxA(0, "Привет, Win32 API", "Первое окно...", MB_ICONINFORMATION|MB_OK);
MessageBoxW(0, L"Привет, Win32 API", L"Первое окно...", MB_ICONINFORMATION|MB_OK);
Неизвестный
27.12.2010, 06:23
общий
в VC++ советую делать так:

- в stdafx.h добавлять строчку (если ещё не добавлена):

#include <tchar.h>

- вместо типа "char" в коде использовать "TCHAR"
- вместо текстовый констант "" использовать макрос _T("") , или TEXT("")
- вместо str... функций использлвать _tcs...-функции, т.е, заменяем:
strlen -> _tcslen
strchr -> _tscchr
и так далее, все названия функций есть в заголовке tchar.h

Зачем всё это надо?

Любая программа может использовать юникодные строчки (16 бит на символ) или обычные (8 бит на символ). Для работы с этими 2 видами строчек используются разные функции. И чтобы не создавать себе проблем в случае внезапного перехода на unicode-версию или обратно, используют макросы, которые при различных режимах сборки приложения превращаются в разные функции, например MessageBox -> MessageBoxA или MessageBoxW, _tcsstr -> strstr или wcsstr.
Кроме перехода, могут быть ситуации, когда один и тот же код используется в разных приложениях. У меня, к примеру, много сервисного кода, работающего со строчками, я его использую и в unicode и обычных приложениях без всяких переделок.
Неизвестный
27.12.2010, 09:25
общий
Спасибо всем! Кажется, разобрался во всём.
Я после удачной компиляции MessageBox компилировал ещё одну программу из 2-го урока - вывод простого окна, которая и компилировалась, и запускалась, и закрывалась, но после неё VS 2005 уже на абсолютно правильный и прежде безошибочно компилируемый код MessageBox вдруг стал писать ошибки. Оказалось, что хоть программа с выводом окна и закрывалась, но была в процессах, занимая более 90% ЦП, потому и MessageBox после неё выводился с ошибками.
Форма ответа