[Win32] I can't run a simple WinMain() funciton...

Started by
5 comments, last by cache_hit 14 years, 1 month ago
main.cpp
#include <windows.h>

int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nShowCmd)
{
	return 0;
}

Errors given:
Quote:Error 1 error LNK2019: unresolved external symbol _main referenced in function ___tmainCRTStartup MSVCRTD.lib(crtexe.obj) Error 2 error LNK1120: 1 unresolved externals C:\Development\IDE\Visual Studio 2010\SAVE\Grand Solution\Debug\Data Manipulation.exe
When I change my code like this: main.cpp
#include <windows.h>

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd)
{	// Line #4 is here
	return 0;
}

Changes: "LPTSTR lpCmdLine" changed to "LPWSTR lpCmdLine". "_tWinMain" changed to "WinMain". "APIENTRY" changed to "WINAPI". Error message changes to:
Quote:Error 1 error C2731: 'WinMain' : function cannot be overloaded c:\development\ide\visual studio 2010\save\...\main.cpp 4
The second WinMain() form is the one exactly same in WinMain() documentation page in MSDN 2008. So what is the problem here? The preprocessor definitions "_UNICODE" and "UNICODE" are defined. SubSystem is set to "Console (/SUBSYSTEM:CONSOLE)". Visual Studio version is 2010 beta 2. [Edited by - Battousai on February 16, 2010 4:19:50 PM]
Advertisement
Problem is that subsystem is set to console. Essentially just ask yourself if you want your program to have a dos window. If the answer is yes, use subsystem:console. If the answer is no, use subsystem:windows. maybe it's not subsystem:windows exactly, I don't remember the exact text. But it's should be obvious from the drop down options.

In the future, you can have the New Project wizard automatically deal with this for you. Just select either Win32 Application or Console Application in the new project wizard depending on which you want.


BTW, if you want your program to have a DOS window, delete the entire WinMain() function and replace it with:

int _tmain(int argc, TCHAR** argv){   return 0;}


Again, this is something that the compiler deals with automatically when you choose the right option from the wizard.
Quote:Original post by cache_hit
Problem is that subsystem is set to console. Essentially just ask yourself if you want your program to have a dos window. If the answer is yes, use subsystem:console. If the answer is no, use subsystem:windows. maybe it's not subsystem:windows exactly, I don't remember the exact text. But it's should be obvious from the drop down options.

In the future, you can have the New Project wizard automatically deal with this for you. Just select either Win32 Application or Console Application in the new project wizard depending on which you want.


BTW, if you want your program to have a DOS window, delete the entire WinMain() function and replace it with:

*** Source Snippet Removed ***

Again, this is something that the compiler deals with automatically when you choose the right option from the wizard.


I used to use CodeBlocks and Dev-C++ IDEs, I had no problem using WinMain() in the console mode. Why doesn't Visual Studio behave like the other IDEs do?

Actually, I used the "New Project Wizard" to generate an initial code template. But I didn't like the main funciton "int _tmain(...)" in it and I changed it to the WinMain() form, then persistent error messages came.

Isn't there any way to use WinMain() in the console mode in Visual Studio?
Now this one is working:

#include <iostream>#include <tchar.h>#include <windows.h>//int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd)int _tmain(int argc, TCHAR** argv){	std::cout << "Working..." << std::endl;	system("pause");	return 0;}


But, why doesn't the WinMain() alternative fails? Though, it worked with other IDEs like CodeBlocks and Dev-C++.
Quote:Original post by Battousai
But, why doesn't the WinMain() alternative fails? Though, it worked with other IDEs like CodeBlocks and Dev-C++.


Different IDEs are different. Visual Studio does extra checking to make sure you're programming the type of application you told it you would. You need to change the project settings so that it knows you're making a Win32 or whatever application.

The easiest way is to just create a new project using one of the templates provided.

- me
If you want it to work in VS look at this code

#include <windows.h>int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd){	return 0;}


There is a slight difference instead of LPWSTR it is just LPSTR, this is the third parameter and it is a string that is the command-line parameters that are passed to the program. I have never used the other IDE's so I couldn't tell as why they work on those and not here. Hope this helps you out.
Quote:Original post by Battousai
Now this one is working:

*** Source Snippet Removed ***

But, why doesn't the WinMain() alternative fails? Though, it worked with other IDEs like CodeBlocks and Dev-C++.


The short answer is that neither WinMain nor main is the *true* entry point for your application. It's actually a function even much deeper than that. Visual C++ is just "helping you" by choosing a signature that it think is probably related to the type of application you're developing. The true entry point is deep in the C runtime library, and is called automatically. This function ultimately ends up calling your entry point after some setup work.

A console app can in theory be ported to other platforms. Because of this, they demand you use the C++ standard defined entry point, which is

int main(int, char**)

windows apps are already highly platform specific, so they give you extra information in the main function that wouldn't even be relevant to you in a console app anyway.


Longer answer depends on some internal details of MSVCRT (Microsoft's implementation of the C runtime library), and is probably not that important anyway.

If you choose a console app, use the tmain entry point. If you choose a windows app, use the WinMain entry point.

This topic is closed to new replies.

Advertisement