Win32 Application LNK2001: unresolved external symbol _main - c++

I have been trying to make a WIN32 Application with a GUI (NOT a simple console application) on VS2012, and I'm stuck with this one error. My project is on Release configuration. My main function looks like this:
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
return DialogBox(hInstance, MAKEINTRESOURCE(IDD_MAIN), NULL, DlgProc);
}
What I've tried:
1) Creating a new WIN32 Project with these settings:
Application Type -> Windows application
Additional options -> Empty Project (With NO SDL!)
No other options checked
2) Changing between Unicode and Multi-Byte Character Sets
3) Changing the SubSystem (from Windows (/SUBSYSTEM:WINDOWS) to Not Set)
4) Adding entry points (main ; _main ; WinMain)
5) Adding #undef _ATL_MIN_CRT (I'm pretty sure it was disabled anyway, but still did it for extra insurance...)
NONE of these solved my issue. I've searched the Internet and haven't found anyone with a similar problem (creating a WIN32 Application) who has solved their issue.
EDIT: I'm also using Allegro 5 library and I'm building the program with /MT .
Any recommendations are welcome.

The problem is that you're using the wrong calling convention for your main function. As the documentation for Name Decoration explains, a symbol with a leading underscore and no other decorations indicates C calling convention.
The signature for your main function should be:
extern "C" __cdecl void main();
Note that neither the return value nor the argument list are part of the name decoration, since the caller is responsible for cleanup. This means that any function signature can be used to satisfy the linker.

After some searching I've found the answer.
All I needed to do was to define ALLEGRO_NO_MAGIC_MAIN .

Related

What does creating a Solution using a template in Visual Studio actually do versus an empty project?

I am following the Intro to C tutorial by Molly Rocket but am running into an issue running the following code in the Debugger in VisualStudio 2019 while using the Empty Project option.
I am using the Empty Project option instead of loading a template because that is what Molly used, while I could just load a template and run the code there instead I would like to know why I am getting this error so I can better understand Visual Studio and C++.
#include <Windows.h>
void learnC(void) {
OutputDebugStringA("Test\n");
}
int CALLBACK WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
learnC();
}
Recieving the error LNK2019 which doesn't help at all because it just a generic catch all error code.
error LNK2019: unresolved external symbol main referenced in function "int __cdecl invoke_main(void)" (?invoke_main##YAHXZ)
I have tried updating the compatiliblity settings of VS2019 as well as other settins that people suggested to use but the error still remains.
Again, when I created the Solution I used the blank document instead of a template becuase that is what Molly Rocket used when writing this code.
When I do use a template (I used the Windows Desktop Application template) and delete all the code and paste in what I had in my original document I do not recieve the Error, and I would like to know why.
Thank you for your time!
When you create an Empty Project, the value of SubSystem defaults to Console.
According to the Doc
An application that uses /SUBSYSTEM:CONSOLE; calls main (or wmain)
An application that uses /SUBSYSTEM:WINDOWS; calls WinMain (or
wWinMain), which must be defined to use __stdcall
As far as I'm concerned you should Set up SubSystem to windows(Properties -> Linker -> System -> SubSystem)
For more details about /SUBSYSTEM (Specify Subsystem), I suggest you could refer to the link: https://learn.microsoft.com/en-us/cpp/build/reference/subsystem-specify-subsystem?view=vs-2019

C++ (VC2010) Help converting console app to hidden Windows app?

I've read more than a dozen pages explaining how to convert a Win32 console application into a Windows application that will run without briefly opening and closing a console window, but I'm too much of a beginner to get it to work.
For example, in VC2010 I made the two changes in the project properties described here:
convert a console app to a windows app
and changed Main to WinMain but of course got error messages from the compiler.
Following other pages, I also tried creating a console application, then, in the Win32 Application Wizard, and changing the Application Type to a Windows application, but I can't figure out what to do next. I've tried changing int Main to int CALLBACK WinMain, but of course that doesn't work either.
Is there anyone who can help a beginner with this? Here is what I think is the relevant part of my code EDIT: the complete code, for anyone who wonders what this is for, is here:
https://www.dropbox.com/s/1h8x1k2zv0lc5d1/vPasteCPlus.txt?dl=0
#include <stdafx.h>
#include <windows.h>
#include <iostream>
#include <fstream>
#include <codecvt> // for wstring_convert
#include <locale> // for codecvt_byname
using namespace std;
// helper to get path to this application
string ExePath() {
char buffer[MAX_PATH];
GetModuleFileNameA( NULL, buffer, MAX_PATH );
string::size_type pos = string( buffer ).find_last_of( "\\/" );
return string( buffer ).substr( 0, pos);
}
int main(int argc, char* argv[])
{
// get the command-line argument if any, and do various things
}
Again, apologies for this beginner question. The only experience I have with C++ is writing console applications, and any advice will be gratefully received.
Ok, so you have opened Visual Studio. And you have Solution Explorer (If not, View -> Solution Explorer).
First of all, to make Windows application, you should change entry point from main() (C++ standard) to Windows-specific WinMain(). See msdn for more detailed description. So, you are changing main() to next one (copy-paste from documentation):
int CALLBACK WinMain(
_In_ HINSTANCE hInstance,
_In_ HINSTANCE hPrevInstance,
_In_ LPSTR lpCmdLine,
_In_ int nCmdShow)
{
return 0;
}
Of course, you should include <Windows.h>, because Windows provides it own API for working with system (such as LPSTR type). In a nutshell, you did all that compiler need to compile your program. And you can build your solution (Build -> Build Solution)... This will lead to linker error:
error LNK2019: unresolved external symbol _main referenced in function ___tmainCRTStartup
Again, compiler did everything you want and compiles your source file into .obj, but, because, your project is configured for Console application, linker needs standard entry point for Console application - main and it can't found (resolve) it in our case, because we changed main to WinMain. To make linker happy, you should tell it:
Right click on project inside Solution Explorer
Then click on Properties:
Go to Configuration Properties -> Linker -> System and set SubSystem to Windows:
Try to build your application again and voila - you have no linker error already because your linker knows now that it need to produce Windows application and found Windows entry point: WinMain() !
About this one:
// get the command-line argument if any, and do various things
you should use lpCmdLine parameter of WinMain(). But be carefully, if you run your program (so.exe, for example) like this one:
so.exe arg1 arg2
lpCmdLine is arg1 arg2 string. There is a lot of stuff of what you can do to get arg1 and arg2 asn an array like in main() argv (with argc), but you can explore:
wWinMain
CommandLineToArgvW
GetCommandLine
and relative stuff (such as wchar_t on Windows)
If this is a Visual Studio project (as the <stdafx.h> strongly indicates) then:
Set the subsystem to Windows in the linker settings.
Set the entry point to mainCRTStartup (which calls standard main).
But are you sure that you want this?
It sounds more that what you want is a Windows service?

How to incorporate Win32 in an SDL project?

I made some software using SDL and OpenGL, and now I would like to add a graphical interface for input, like some textboxes and buttons. I realize that this probably would have to be in a separate window, which I don't mind, but I have no clue how to incorporate Win32 functionality in my project. I tried changing the definition of my main function from
int main(int argc, char **argv)
{
...
}
to
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, LPSTR lpCmdLine, int cmdShow)
{
...
}
But I get an errors that say:
LNK2005: _WinMain#16 already defined in SDL2main.lib (SDL_windows_main.obj)
LNK2005: _WinMain#16 already defined in Source.obj
LNK2019: unresolved external symbol _SDL_main referenced in function _main
I'm using Visual Studio 2012.
Is there a way to solve this, or is there an alternative way to create forms in c++?
Thanks
SDL defines main as a macro. It's like the ultimate horror show. Mixing Microsoft's WinMain monstrosity into that might seem appropriate, of course, but it isn't needed for anything.
Instead just keep your main.
If I had committed to using SDL (which, considering the above, I would never do), then I would first of all check out what SDL offers in the way of textboxes and buttons and such. If none, then just include <windows.h> properly (defining STRICT and NOMINMAX and UNICODE first), and use the API. But for that I suggest learning that API first by creating some pure API programs, with no interfering SDL.

How do I set WinMain as entry point?

I've deleted the _tmain() method which the IDE generated because I find no sense having two entry points after adding my WinMainentry. And yes, this is my first ever C++ application and I am a newbie, but please be nice.
So that's all I got:
// Included headers:
#include "stdafx.h"
#include <iostream>
#include <Windows.h>
// Shortened namespaces:
using namespace std;
// The main entry of the application:
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )
{
MessageBox( NULL, L"Hello World!", L"Just another Hello World program!", MB_ICONEXCLAMATION | MB_OK );
return 0;
}
// End of file.
When I try to build and run I get this error:
error LNK2019: unresolved external symbol _main referenced in function ___tmainCRTStartup
error LNK1120: 1 unresolved externals
I realise the entry point is missing, But where can I set WinMain as the entry point? I just took a look in the properties of the project itself and found nothing.
Note that I've started the project as a console application, But now I am trying to turn it into a regualr windows application.
Thanks.
You need to change the subsystem to Windows.
Project->Properties->Linker->System change Subsystem to /SUBSYSTEM:WINDOWS
If you have further trouble with it then start all over again, selecting Win32 Project instead of Win32 Console.
It sounds you are trying to build a console application with code that you imported from a windows application.
Console applications use a main (or _tmain) entry point, whereas windows applications use a WinMain (or _tWinMain) entry point.
Edit: Indeed changing the linker option as Benjamin told you will solve your immediate problem but you are likely to meet other issues later with such hybrid projects. For example you may include some code relying on the _CONSOLE preprocessor symbol.
You can of course adjust this latter setting yourself too but better restart from a clean win32 template as Scott and Hans suggested.

SFML linker error: unresolved external symbol _WinMain#16, Visual Studio 2012

I was able to get tutorial #1 to compile fine. But I can't get the 2nd one to compile.
When you do new -> Project, maybe one of those settings are interfering? Pretty sure I did empty project, else console.
What's wrong?
compile error:
Error 1 error LNK2019: unresolved external symbol _WinMain#16 referenced in function
___tmainCRTStartup C:\...\02-videomode-iterate\MSVCRTD.lib(crtexew.obj) 02-videomode-iterate
Error 2 error LNK1120: 1 unresolved externals C:\...\Debug\02-videomode-iterate.exe 02-videomode-iterate
entire source:
#include <SFML/Window.hpp>
int main()
{
sf::Window App(sf::VideoMode(800, 600, 32), "SFML-tut: 02");
bool Running = true;
while (Running)
{
App.Display();
}
return EXIT_SUCCESS;
}
Project settings:
include dir, lib: dir set correctly.
c++ -> preprocessor -> preprocessor definitions:
SFML_DYNAMIC
linker -> input
tried: sfml-window.lib and sfml-window-d.lib ( visual studio seems to always use debug mode at start? but tutorial #1 only worked when I didn't use -d version.
subsystem:
/SUBSYSTEM:WINDOWS
When you set the /SUBSYSTEM:WINDOWS flag, the linker will look for a WinMain function rather than the conventional main. You have two options:
Change to /SUBSYSTEM:CONSOLE. You will get an annoying (or perhaps helpful) console window, which you can get rid of with FreeConsole.
Change main to WinMain with the following signature:
int CALLBACK WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow
);
Unless you need to access argc and argv, this change shouldn't cause too much trouble.
Edit: Perhaps this is worth a look too (copied from the second tutorial):
Under Windows operating systems, you may have created a "Windows
Application" project, especially if don't want the console to show up.
In such case, to avoid replacing main by WinMain, you can link with
SFML_Main static library and keep a standard and portable main entry
point.
So, I suppose that boils down to adding sfml-main.lib (or similar) to the list of libraries to link with.