We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 4034

Summary: Do we really need _DllMainCRTStartup() in every Windows build?
Product: SDL Reporter: Andreas Falkenhahn <andreas>
Component: *don't know*Assignee: Sam Lantinga <slouken>
Status: RESOLVED FIXED QA Contact: Sam Lantinga <slouken>
Severity: normal    
Priority: P2 CC: sezeroz
Version: HG 2.1   
Hardware: x86   
OS: Windows 7   

Description Andreas Falkenhahn 2018-01-09 21:52:12 UTC
In src/SDL.c there is this code:

#if defined(__WIN32__)

#if !defined(HAVE_LIBC) || (defined(__WATCOMC__) && defined(BUILD_DLL))
/* Need to include DllMain() on Watcom C for some reason.. */

BOOL APIENTRY
_DllMainCRTStartup(HANDLE hModule,
                   DWORD ul_reason_for_call, LPVOID lpReserved)
{
    switch (ul_reason_for_call) {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}
#endif /* building DLL with Watcom C */

#endif /* __WIN32__ */

The comment says that this is needed on Watcom C for some reason but why is it included then when building with Visual C as well? Shouldn't it be only included when compiling on Watcom C then?

I'm asking because this code caused me a lot of headaches because I'm building a DLL that contains SDL and I link using /MT and the _DllMainCRTStartup() symbol obviously led to lots of trouble but it wasn't clear to me where the problem was because all I got from the linker was:

LNK2019: unresolved external symbol _main referenced in function ___tmainCRTStartup 

So I had to got through each and every object to see what the culprit was. See here for the full story:
https://stackoverflow.com/questions/25067151/lnk2019-unresolved-external-symbol-main-referenced-in-function-tmaincrtstar/48177067#48177067

So if it isn't necessary on Visual C, please just leave that symbol out on Visual C so that it no longer leads to any trouble. Thanks.
Comment 1 Ryan C. Gordon 2018-02-18 04:53:46 UTC
(In reply to Andreas Falkenhahn from comment #0)
> So if it isn't necessary on Visual C, please just leave that symbol out on
> Visual C so that it no longer leads to any trouble. Thanks.

So this goes back to this revision: https://hg.libsdl.org/SDL/rev/450721ad5436

...replacing the DllMain that landed in revision _36_.

Originally it was apparently necessary for Watcom and Windows CE builds, so its possible the !HAVE_LIBC is an incorrect test.

Sam, can you say if this is still needed? Maybe it was some specific version of Visual Studio that didn't cooperate?

--ryan.
Comment 2 Sam Lantinga 2018-02-18 16:58:09 UTC
We don't support Windows CE anymore, so I went ahead and removed it.
https://hg.libsdl.org/SDL/rev/0ee27779b86f

Thanks!
Comment 3 Sam Lantinga 2018-02-18 17:09:14 UTC
Actually, this is needed for building with Visual Studio with both /MT and /MD.
With the change above, I get:
1>     Creating library C:\projects\SDL\VisualC\Win32\Debug\SDL2.lib and object C:\projects\SDL\VisualC\Win32\Debug\SDL2.exp
1>LINK : error LNK2001: unresolved external symbol __DllMainCRTStartup@12

I'm not sure why the linker was confused in your case, so I'm reverting the change and reopening the bug.
Comment 4 Ozkan Sezer 2018-02-18 17:36:43 UTC
As I understand it, this is needed only for DLL builds, so I think the
parenthesizing is the only thing wrong here: Does the following change
help?

--- a/src/SDL.c
+++ b/src/SDL.c
@@ -452,9 +452,9 @@
 }
 
 #if defined(__WIN32__)
 
-#if !defined(HAVE_LIBC) || (defined(__WATCOMC__) && defined(BUILD_DLL))
+#if (!defined(HAVE_LIBC) || defined(__WATCOMC__)) && defined(BUILD_DLL)
 /* Need to include DllMain() on Watcom C for some reason.. */
 
 BOOL APIENTRY
 _DllMainCRTStartup(HANDLE hModule,
Comment 5 Sam Lantinga 2018-02-18 17:44:59 UTC
BUILD_DLL isn't defined in the current SDL projects. We could add that, but that would break everyone who has custom SDL projects. I'd rather not do that in a minor point release.
Comment 6 Ozkan Sezer 2018-02-18 17:53:41 UTC
Yeah, just noticed that myself (sorry). That really needs cleaning up
in future releases.

For now, _maybe_ invent another condition of !defined(SDL_NO_DLL), so
that users can define that for their own static builds?? Like:

--- a/src/SDL.c
+++ b/src/SDL.c
@@ -451,7 +451,7 @@
 #endif
 }
 
-#if defined(__WIN32__)
+#if defined(__WIN32__) && !defined(SDL_NO_DLL)
 
 #if !defined(HAVE_LIBC) || (defined(__WATCOMC__) && defined(BUILD_DLL))
 /* Need to include DllMain() on Watcom C for some reason.. */
@@ -469,8 +469,8 @@
     }
     return TRUE;
 }
-#endif /* building DLL with Watcom C */
+#endif
 
-#endif /* __WIN32__ */
+#endif /* __WIN32__ && !DLL */
 
 /* vi: set sts=4 ts=4 sw=4 expandtab: */
Comment 7 Sam Lantinga 2018-02-21 17:41:39 UTC
Okay, you can now define SDL_STATIC_LIB when building SDL, and that will prevent _DllMainCRTStartup() from being defined.
https://hg.libsdl.org/SDL/rev/e6fc3ef41ffd

Cheers!