помилка LNK2019: невирішений зовнішній символ _WinMain @ 16, на який посилається функція ___tmainCRTStartup


143

Хоча я запускаю простий код, як показано нижче, у мене є дві помилки:

#include <iostream>
#include <string>
using namespace::std;

template <class Type>
class Stack
{
public:
    Stack (int max):stack(new Type[max]), top(-1), maxsize(max){}
    ~Stack (void) {delete []stack;}
    void Push (Type &val);
    void Pop (void) {if (top>=0) --top;}
    Type& Top (void) {return stack[top];}
    //friend ostream& operator<< (ostream&, Stack&);
private:
    Type *stack;
    int top;
    const int maxSize;
};

template <class Type>
void Stack <Type>:: Push (Type &val)
{
    if (top+1<maxsize)
        stack [++top]=val;
}

Помилки:

MSVCRTD.lib (crtexew.obj): помилка LNK2019: невирішений зовнішній символ, на який _WinMain@16посилається функція___tmainCRTStartup

Що я повинен зробити?


1
Це все код? Де ваша основна функція?
Коннман

2
Також виглядає, що тип проекту встановлений неправильно. Помилка лінкера щодо WinMain означає, що ви намагалися створити проект Win32. Якщо ви просто хочете щось вивести текст у командний рядок, спробуйте змінити тип проекту на Console.
Кіланаш

4
До речі, якщо ви отримуєте помилки компілятора / лінкера, ви не "запускаєте" код.
Андре Карон

1
Я спробував змінити тип проекту, але проект = exe працював замість консолі.
Дом

Відповіді:


352

У цьому проблема з лінкером.

Спробуйте змінити властивості -> Linker -> System -> SubSystem (у Visual Studio).

від Windows (/ SUBSYSTEM: WINDOWS) до консолі (/ SUBSYSTEM: CONSOLE)

Цей мені допоміг


3
У мене те саме питання. Ваша відповідь не допомагає. Будь-які інші пропозиції?
Parth Sane

1
У мене була ця проблема під час використання MS Visual Studio. Якщо ваше оточення відрізняється, можливо, вам доведеться виправити це по-іншому. Але це все ж має бути проблемою зв’язку.
Богдан

2
Якщо ви використовуєте tWinMainв якості своєї основної функції, ви повинні включити tchar.h або змінити його на WinMainабо wWinMainзалежно від того, чи є ваш додаток Unicode. Якщо цього не зробити, це призводить до помилки лінкера навіть при правильній підсистемі. (/ SUBSYSTEM: WINDOWS)
ліза

Це допомогло мені, крім того, що мені довелося також відключити антивірус Avast .
XCS

1
Це спрацювало лише після того, як я вибрав "всі конфігурації" як для платформи, так і для типу. Вибравши "build" на "Solution", спробували створити все, і перший спробував НЕ той, який був вказаний для консолі підсистеми.
Джозеф Стейтсон

83

Як згадували інші, ви можете змінити підсистему на консоль, і помилка усунеться.

Або якщо ви хочете зберегти підсистему Windows, ви можете просто підказати, яка ваша точка входу, тому що ви не визначилися ___tmainCRTStartup. Для цього можна додати наступне: Властивості -> Linker -> Командний рядок :

/ Вхід: "mainCRTSзапуск"

Таким чином ви позбудетеся від вікна консолі.


3
+1: "Таким чином ви позбудетеся від вікна консолі." - Класно! Навчився що-н. новий сьогодні!
Валентин Хайніц

1
+1 за пораду, я намагався розібратися в цьому приблизно 20 хвилин, оскільки за допомогою SFML я можу просто вказати підсистему Windows, з GLFW, що, очевидно, не так вже дякує (=
Даніель

14

Якщо у вас є ця проблема і ви використовуєте Qt - вам потрібно зв’язати qtmain.lib або qtmaind.lib


Це на Project -> Властивості -> Linker -> Input. Додати $(QTDIR)\lib\qtmaind.libдо додаткових залежностей.
mathiasfk

1
Додавання CONFIG += consoleдо .proфайлу
вирішило

12

Окрім того, щоб змінити його, Console (/SUBSYSTEM:CONSOLE)як вже говорили інші, можливо, вам знадобиться змінити точку входу у Властивості -> Linker -> Advanced -> Point Entry. Встановіть його на mainCRTSзапуск .

Здається, що Visual Studio може шукати функцію WinMain замість основної, якщо не вказано інше.



7

Якщо ви використовуєте набір символів Unicode, але запис не було встановлено, ви можете вказати / ENTRY: "wWinMainCRTStartup"


рятування життя для мене! Я використовував cmake + mfc (unicode)
malat

4

я не бачу основної функції.

будь ласка, переконайтеся, що вона має основну функцію.

приклад:

int main(int argc, TCHAR *argv[]){

}

сподіваюся, що це працює добре. :)


Це не допомагає. Лінкер скаржиться на невизначений пункт входу WinMain . Визначення викликаної точки входу mainнічого не вирішує.
Неочікуваний

Лінкер намагається вирішити різні main/ WinMainверсії, і якщо жодна з них не знайдена, він каже, що WinMain @ 16 не знайдено , але це повідомлення не зовсім правильне.
Lorinczy Zsigmond

3

Якщо ваш проект Dll, то випадок може бути тим, що лінкер хоче створити консольну програму. Відкрийте властивості проекту. Виберіть Загальні установки. Виберіть там тип конфігурації Динамічна бібліотека (.dll).


У мене є саме така проблема, але хоча .dllкомпілятор встановлений все ще намагається створити додаток Windows.
Томаш Зато - Відновіть Моніку

3

Я не впевнений, де розмістити цю свою відповідь, але думаю, що це правильне місце. Сьогодні я зіткнувся з цією самою помилкою і переключення підсистем нічого не змінило.

Зміна 64-бітових файлів lib на 32-бітну (x86) зробила для мене трюк, я сподіваюся, що це допоможе комусь там!


Я спробував це і працював, хоча перекомпіляція залежностей до тих же цілей також працює.
Джеймі Ніколл-Шеллі

також працював для мене ... схоже, майстер тестування
модулів

3

Якщо ви дійсно хочете використовувати _tWinMain () замість main (), переконайтеся, що у відповідній конфігурації вашого проекту

  1. Linker-> System -> SubSystem => Windows (/ SUBSYSTEM: WINDOWS)
  2. C / C ++ -> Препроцесор -> Визначення препроцесора => Замінити _CONSOLE на _WINDOWS
  3. У файл c / cpp, де визначено _tWinMain () , додайте:

    #include <Windows.h> #include <tchar.h>


2

Ви намагалися перетворити цей вихідний файл у виконуваний файл, що очевидно неможливо, оскільки обов'язкова точка входу, mainфункція, не визначена. Додайте файл main.cpp та визначте основну функцію. Якщо ви працюєте над командним рядком (в чому я сумніваюся), ви можете додати /cлише компіляцію, а не посилання. Це створить лише об’єктний файл, який потрібно пов’язати або з статичною, або з спільною lib, або з додатком (у такому випадку вам знадобиться файл з викидом з основним визначеним).

_WinMainє ім'ям Microsoft mainпри посиланні.

Крім того : ви не використовуєте код ще, ви компіляції (і посилання) його. C ++ - це не інтерпретована мова.


5
Насправді йому потрібна WinMain(HINSTANCE, HINSTANCE, LPSTR, INT)точка входу. Ця помилка лінкера вказує на те, що проект будується для підсистеми Windows, а не консольної підсистеми.
Адам Марас

@Adam: Ага, Qt :) мене зіпсував Qt :) (що ефективно приховує від вас WinMain).
рубенвб

WinMain призначений лише для програм Windows. У додатках консолей використовується інша назва _tmain, яка має значення main або wmain, залежно від налаштування Unicode / MBCS.
Стів Таунсенд

@AdamMaras, ідеально. Я шукав необхідну капіталізацію та прототип. Він прекрасно працює зараз. Дякую!
Synetech

_WinMain@16є оформленим символом наданої користувачем точки входу, що викликається кодом запуску в CRT, під час націлювання на підсистему Windows. Це не "ім'я Microsoft дляmain з'єднання" . Якщо ви орієнтуєтесь на підсистему консолі, CRT, що постачається з Visual Studio, викличе точку входу з назвою main. Якщо не визначено, лінкер поскаржиться на зниклий символ, який називається _main.
Неочікуваний

1

Якщо ви використовуєте CMake, ви також можете отримати цю помилку, встановивши SET(GUI_TYPE WIN32)консольний додаток.


1

Згадані вище ерудитні пропозиції вирішать проблему в 99,99% випадків. Мені пощастило, що вони цього не зробили. У моєму випадку виявилося, що я включав файл заголовка з іншого проекту Windows. Звичайно, в самому дні цього файлу я знайшов директиву:

#pragma comment(linker, "/subsystem:Windows")

Потрібно сказати, що видалення цієї лінії вирішило мою проблему.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.