WinMain Cannot be Overloaded

It sounds like the value of _UNICODE is different at different places in your code. Juce will work with unicode either turned on or off, but it must be consistent across your whole project.

Maybe try setting _UNICODE=1 in your project settings, or look in these 3rd party headers to see if they mess around with it.

I don't think that it is unicode which is the problem.

This is the definition order in juce_Initialisation.h:

#if defined (WINAPI) || defined (_WINDOWS_)
 (...)
#elif defined (_UNICODE)
 (...)
#else
 (...)
#endif

_UNICODE is presumably defined everywhere, but it is superseded by the "WINAPI || _WINDOWS_" definition in some files:

"Using WINAPI || _WINDOWS_" ((...) juce_audio_devices\juce_audio_devices.cpp)
"Using WINAPI || _WINDOWS_" ((...) juce_audio_processors\juce_audio_processors.cpp)
"Using _UNICODE" ((...) juce_data_structures\juce_data_structures.cpp)
"Using WINAPI || _WINDOWS_" ((...) juce_graphics\juce_graphics.cpp)
"Using WINAPI || _WINDOWS_" ((...) juce_events\juce_events.cpp)
"Using WINAPI || _WINDOWS_" ((...) juce_gui_basics\juce_gui_basics.cpp)
"Using WINAPI || _WINDOWS_" ((...) juce_gui_extra\juce_gui_extra.cpp)
"Using WINAPI || _WINDOWS_" ((...) juce_opengl\juce_opengl.cpp)
"Using WINAPI || _WINDOWS_" ((...) juce_video\juce_video.cpp)
"Using _UNICODE" (..\..\Source\Main.cpp)
(...)

All the rest => "Using _UNICODE"

The important thing to notice is that the Main.cpp is using the "_UNICODE" WinMain definition.

This is no problem until something causes for example winbase.h to be included. (Like Ogre or Boost)

When <Ogre.h> is included at any random location in your project it causes winbase.h to be included, but the Main.ccp will still use the "_UNICODE" version of WinMain => collision => "second C linkage of overloaded function not allowed"

At least that is my guess what is happening...

This can be 'dirty hack fixed' by including <Ogre.h> (or Boost or whatever...) as the first header file in your Main.cpp (even before the juce header) => winbase.h is included first => Main.cpp is using the "WINAPI || _WINDOWS_" definition of WinMain => no collision anymore

But this of course should not be the recommended solution... :)

 

Hmm, doing some research, it seems that the unicode line could actually be removed without any ill effects, so leaving:


 #if JUCE_WINDOWS && ! defined (_CONSOLE)
  #if defined (WINAPI) || defined (_WINDOWS_)
   #define JUCE_MAIN_FUNCTION       int __stdcall WinMain (HINSTANCE, HINSTANCE, const LPSTR, int)
  #else
   #define JUCE_MAIN_FUNCTION       int __stdcall WinMain (void*, void*, const char*, int)
  #endif

AFAICT the unicode version should actually be called wWinMain, but it's not actually needed since code elsewhere gets the command line params, so I *think* it should just work ok without it..

But this wouldn't fix the problem.

If the "_UNICODE" part is removed the Main.cpp will use the ELSE part which is:
int __stdcall WinMain (void*, void*, const char*, int)

What we actually need the Main.cpp to use is the first definition:
int __stdcall WinMain (HINSTANCE, HINSTANCE, const LPSTR, int)

I think this "autodetection" mechanism simply has no chance to behave correctly, because it can't divince that winbase.h is included somewhere in the application after Main.cpp has already decided to use the wrong definition.

I am not sure whether this is the best solution, but i would suggest introducing another custom flag like "FORCE_WINAPI_MAIN" or whatever you like to call it:

#if defined (WINAPI) || defined (_WINDOWS_) || defined (FORCE_WINAPI_MAIN)
 #define JUCE_MAIN_FUNCTION int __stdcall WinMain (HINSTANCE, HINSTANCE, const LPSTR, int)

Then people who would like to use Ogre or Boost or whatever could simply add this flag to the "Preprocessor definitions" of their project in the Introjucer to tell JUCE that it should ignore "autodetection" and simply use the first definition.

If the "_UNICODE" part is removed the Main.cpp will use the ELSE part which is:
int __stdcall WinMain (void*, void*, const char*, int)

What we actually need the Main.cpp to use is the first definition:
int __stdcall WinMain (HINSTANCE, HINSTANCE, const LPSTR, int)

Yeah, I know. Those two definitions are equivalent. That's why I suggested it.

Yeah, I know. Those two definitions are equivalent. That's why I suggested it.

I just tested your suggestion and the compiler wasn't happy with it.

Exactly the same error: "second C linkage of overloaded function not allowed"

 

EDIT:

int __stdcall WinMain (void*, void*, const char*, int) => error

int __stdcall WinMain (HINSTANCE, HINSTANCE, const char*, int) => error

int __stdcall WinMain (void*, void*, const LPSTR, int) => error

 

I don't know why, but it only works if the definition is exactly:

int __stdcall WinMain (HINSTANCE, HINSTANCE, const LPSTR, int)

FYI I tried this on windows and did finally manage to come up with some code that seems to work in all situations. Was surprisingly hard to find some syntax that worked either with or without windows.h being included.

Thank you very much jules, it works perfectly fine now.

May this thread rest in peace. :)