Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.75/40: Рейтинг темы: голосов - 40, средняя оценка - 4.75
5 / 5 / 1
Регистрация: 25.10.2013
Сообщений: 230

Точка входа отличная от main/WinMain

28.01.2015, 09:40. Показов 8644. Ответов 32
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Случайно наткнулся на код и прямо-таки заинтересовало:
Существует еще один вид стартовой функции, о котором, судя по всему, не знает по меньшей мере половина программистов, пишущих для Windows. Суть проблемы заключается вот в чем – на самом деле, во время компиляции приложения, кроме написанного программистом кода компилятор вставляет свой собственный код, который инициализирует всякие интересные штуки и только когда сочтет нужным – то передает управление функциям main/WinMain. Сам добавляемый код можно посмотреть в файле <пусть к установленной VS>/VC/crt/src/crt0.c.
Так как в некоторых случаях этот код совершенно не нужен, то я покажу, как от него обычно избавляются, а заодно – как можно рисовать, не создавая своего окна, прямо поверх рабочего стола и окон других приложений. Итак, создаем новый проект HelloWorld3, все абсолютно аналогично прежним. После создания добавляем main.c со следующим кодом:
C++
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
#define STRICT
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#pragma comment (linker,"-merge:.rdata=.text")
const CHAR szMessage[]="Hello, world!";
 
void CenterText(HDC hDC,int x,int y,LPCTSTR szMessage,int point)
{
    HFONT hFont=CreateFont(
        point * GetDeviceCaps(hDC, LOGPIXELSY) / 60,
        0, 370, 0, FW_BOLD, TRUE, FALSE, FALSE,
        RUSSIAN_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS,
        PROOF_QUALITY, VARIABLE_PITCH, "Times New Roman");  // Создаем новый шрифт
    HGDIOBJ hOld = SelectObject(hDC, hFont);    // Сохраняем старый шрифт
    SetTextAlign(hDC, TA_CENTER | TA_BASELINE); // Текст выровняем по центру
    SetBkMode(hDC, TRANSPARENT);    // Прозрачность, чтоб текст не оказался в квадратной рамке с цветом фона
    SetTextColor(hDC, RGB(0x40,0xAA,0));    // Цвет текста
    TextOut(hDC, x, y, szMessage, strlen(szMessage));   // Рисуем текст на поверхности
    SelectObject(hDC, hOld);    // Возвращаем старый шрифт
    DeleteObject(hFont);        // Удаляем наш кастомный шрифт
}
 
void WinMainCRTStartup()
{
    // HDC - это такая поверхность, по которой планируется рисовать
    // В данном случае мы будем рисовать по поверхности всех имеющихся
    // мониторов. А в общем случае она может быть создана и для принтера
    // и для других экзотических устройств
    HDC hDC = CreateDC("DISPLAY", NULL, NULL, NULL);
    while(1)    // Повторять будем бесконечно
    {
        // Выводим текст
        CenterText(hDC, GetSystemMetrics(SM_CXSCREEN) / 2,
            GetSystemMetrics(SM_CYSCREEN) / 2, szMessage, 72);
        Sleep(100); // Ждем 1/10 секунды, чтоб не забивать процессор
    }
    // Сюда выполнение не дойдет, задачу нужно завершить через список процессов
    ReleaseDC(NULL, hDC);
    ExitProcess(0);
}
Теперь требуется настроить свойства проекта - щелкаем правой кнопкой в окне Solution Explorer по названию проекта HelloWorld3, выбираем Properties. В дереве открываем Configuration Properties/Linker/System, ставим в свойстве SubSystem значение Windows. Свойство SubSystem как раз и определяет, как будет компилироваться приложение – как консольное (/SUBSYSTEM:Console) или как оконное (/SUBSYSTEM:Windows). Если его не устанавливать, то оно само попытается определить тип подсистемы по имени стартовой функции. Однако, если функция имеет нестандартное имя, как в нашем примере – то его придется указывать явно. Помимо этих двух типов приложений, в списке имеются также и другие, но к теме уроков они не относятся.
Дальше открываем Configuration Properties/Linker/Advanced, в свойство Entry Point записываем название функции, с которой хотим начать выполнение – WinMainCRTStartup.
Собственно:
1>MSVCRTD.lib(crtexew.obj) : error LNK2019: ссылка на неразрешенный внешний символ _WinMain@16 в функции ___tmainCRTStartup
1>c:\users\w\documents\visual studio 2013\Projects\Overlay\Debug\HelloWorld.e xe : fatal error LNK1120: неразрешенных внешних элементов: 1
Насколько я понимаю проблема как раз в SubSystem. Несколько не понятно, что именно там необходимо ввести в качестве значения. Просто Windows? /SUBSYSTEM:Windows? Перепробовал - толку нет. Среда MSVS2013.
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
28.01.2015, 09:40
Ответы с готовыми решениями:

Ошибка: In function main: 18 undefined reference to WinMain
Создайте класс, содержащий 2 закрытые переменные (катеты прямоугольного треугольника) и открытые функции (для присвоения значений...

Настройка размера окна при открытии программы (main(), не WinMain()
Доброго времени суток, форумчане! Во первых, хочу вас всех поблагодарить за помощь, благодаря вам я написал свою первую серьёзную...

[ERROR] id returned 1 exit status | main.c:(text.startup+0xa7):undefined reference to 'WinMain@16'
Здравствуйте. Помогите узнать в чем ошибка. По ходу с компилятором что-то не так. . . использую Dev C++ #include &lt;iostream&gt; ...

32
Модератор
Эксперт по электронике
8982 / 6749 / 921
Регистрация: 14.02.2011
Сообщений: 23,875
28.01.2015, 14:34
Студворк — интернет-сервис помощи студентам
а может и меньше
один из байтов при юникоде может быть 0
что при приведении к char* даст конец строки

Добавлено через 2 минуты
Убежденный,
вроде была какая то универсальная функция (макрос) которая в зависимости юникод или нет меняла функции определения длинны строки?
точно сейчас не помню
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
28.01.2015, 14:40
_tcslen.
Но я таким маразмом избегаю пользоваться (ибо Unicode должен
быть везде и уже давно, хватить уже этих OEM/ASCII/ISO/etc).
0
5 / 5 / 1
Регистрация: 25.10.2013
Сообщений: 230
28.01.2015, 15:11  [ТС]
Цитата Сообщение от Убежденный Посмотреть сообщение
Так если все в Unicode, надо вместо strlen ставить wcslen.
Под "все" подразумевались настройки проекта. Результат разве что новые иероглифы появились. Причем почему-то они накладываются друг на друга. Если ручками увеличить длину, то можно увидеть частично перекрытое иерогилфами "Times new Roman", даже если изменить шрифт на Arial...

Добавлено через 5 минут
_tcslen так же ничего нового не привнес. Картина полностью идентичная wcslen.
0
14 / 14 / 8
Регистрация: 31.05.2012
Сообщений: 210
Записей в блоге: 2
28.01.2015, 15:31
какой смысл менять имя точки входа на своё? отдашь ты кодить другому человеку проект и будет он там тыкать.. время тратить. искать этот main ... а он у вас по другому называется.. -_- бред ИМХО
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
28.01.2015, 15:41
Как это
Цитата Сообщение от DarkMasterW Посмотреть сообщение
у меня вроде и так все юникоде.
Соотносится вот с этим:
Цитата Сообщение от DarkMasterW Посмотреть сообщение
const CHAR szMessage[]="Hello, world!";
?
0
5 / 5 / 1
Регистрация: 25.10.2013
Сообщений: 230
28.01.2015, 15:59  [ТС]
C++
1
2
CenterText(hDC, GetSystemMetrics(SM_CXSCREEN) / 2,
            GetSystemMetrics(SM_CYSCREEN) - 100, (LPCTSTR)szMessage, 36);
Дык мы же вроде приводим к типу? Или после этого szMessage будет передано не как юникод?
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
28.01.2015, 16:04
Цитата Сообщение от DarkMasterW Посмотреть сообщение
Дык мы же вроде приводим к типу? Или после этого szMessage будет передано не как юникод?
Как юникод. Но проблема в том, что будь эта строка правильного типа, то она занимала бы гораздо больше места в байтах. А так получилось, что функция пытается считать переданные байты как юникод, хотя на самом деле юникодом они не являются.
0
5 / 5 / 1
Регистрация: 25.10.2013
Сообщений: 230
28.01.2015, 16:08  [ТС]
Т.е. при этом не будет фактической конвертации, а просто произойдет копирование куска памяти?
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
28.01.2015, 16:14
Цитата Сообщение от DarkMasterW Посмотреть сообщение
Т.е. при этом не будет фактической конвертации, а просто произойдет копирование куска памяти?
Откуда ей взяться, когда ты просто насильно сменил тип указателя, нарушив типизацию. Соответственно за последствия отвечаешь только ты
0
5 / 5 / 1
Регистрация: 25.10.2013
Сообщений: 230
28.01.2015, 16:22  [ТС]
Мда... Заблуждения были страшные и тянулись они давно. Неправильные выводы сделал по старым граблям. Пошел искать конвертацию
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
28.01.2015, 16:47
Цитата Сообщение от DarkMasterW Посмотреть сообщение
Пошел искать конвертацию
Зачем? Определи массив символов сразу как юникод и все. Компилятор поместит туда UTF-16 строку.
C++
1
const TCHAR szMessage[]=L"Hello, world!";
0
5 / 5 / 1
Регистрация: 25.10.2013
Сообщений: 230
28.01.2015, 16:55  [ТС]
Не ну так уже сделал и работает) Правда есть подозрение, что поверхность была очень некорректно испохаблена в ходе тестов и ее закрытие ни к чему не приводит(остались старые надписи по диагонали, но новые выводятся корректно). Практического смысла в конвертации нет, это скорее для общего развития.
0
1 / 1 / 0
Регистрация: 22.11.2014
Сообщений: 2
08.10.2018, 11:01
extern "C" void WinMainCRTStartup()
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
08.10.2018, 11:01

Не могу запустить WPF проект. Не найдена точка входа Main. Ничего не понимаю...
Создал проект WPF. Удалил MainWindow.xaml, MainWindow.xaml.cs, App.xaml, App.xaml.cs. Потом такие же файлы скопировал с другого проекта и...

Что такое точка входа? (opengl32.dll была загружена, но найти точку входа для DllRegisterServer не удалось.)
:help: при открывании игр показывает окно: RegSvr32 opengl32.dll была загружена, но найти точку входа для DllRegisterServer не...

Вызов конструктора происходит до входа в main
Дебажу один большой проект Первый брейкпоинт у меня стоит на первой строке в main(), но при этом отладчик сначала попадает в...

Программа не содержит статистического метода Main, подходящего для входа
Помогите пожалуйста, ошибку эту выдает using System; using System.Collections.Generic; using System.Linq; using System.Text; ...

Программа не содержит статического метода main подходящего для точки входа
Вчера оба проекта нормально компилировались, а сегодня выдает ошибку &quot;Программа не содержит статического метода main подходящего для точки...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
33
Ответ Создать тему
Новые блоги и статьи
GitDOS: Когда я решил скрестить MS-DOS, GitHub и Claude
MaGz GoLd 08.07.2026
Привет, Киберфорум! Хочу поделиться своим проектом, который, надеюсь, вас заинтересует. GitDOS — это веб-приложение, которое позволяет запускать DOS в браузере с тремя крутыми фичами: диски живут в. . .
Учебный мини "цифровой двойник" = (Сервер = Java + Flask_питон )+(3D = Гугловскаая 4T nvideo + google colab) +( WMS = Odoo на Docker)
anaschu 07.07.2026
Увидел в требованиях к вакансии создателя имитационных моделей связку (REst + Api + WMS + Anylogic + питон + 3D Nvideo), и решил посмотреть, что это такое. Из этого всего я работал более менее. . .
Море в объективе
kumehtar 06.07.2026
Хотел написать много проникновенных слов, но передумал. Оно само - говорит. Кто слышит тот слышит.
Doom для терминала без стрельбы и монстров. 3D Raycasting на ascii.
dcc0 05.07.2026
Попросил нейронную сеть deepai. org написать рейкастинг 3D с библиотекой ncurses для Linux. Чтобы можно было ходить на стрелочки. Чтобы стены были отрисованы символами. Справилась. Первый вариант. . .
Установка статуса документа по условию
Maks 05.07.2026
Алгоритм из решения ниже реализован на нетиповом документе "НарядПутевка" разработанного в КА2. Задача: в табличной части "Материалы" документа при записи автоматически устанавливать статус. . .
Сезонность и суточность закисления почв
anaschu 04.07.2026
200 часов это все равно моловато. Есть ситуации, но нестандартные, когда смена происходит за 5 лет. Но обычно это 50 лет и более. Наверное, закисление почвы происходит сезонно в средней. . .
В чем ценность человеческого опыта в глобальном смысле?
kumehtar 03.07.2026
Возможно, ценность человека не в том, что он однажды достигает мудрости, а в том, что он становится носителем карты пути. Он знает не только истину, но и последовательность внутренних изменений,. . .
интеграция AnyLogic с самописным REST API и переход на Odoo
anaschu 03.07.2026
Успешная интеграция AnyLogic с самописным REST API и переход на промышленную Odoo WMS Сегодня проделал огромный путь от простой симуляции физических процессов до построения полноценной. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru