views:

46

answers:

2
+2  Q: 

DLL linker issue

I am compiling a DLL twice (once for x86, once for x64) and I have set /ENTRY to "DllMain". I am using the /MT runtime library option to statically link against the runtime library. This all work fine when doing the x86 build, but the x64 build fails with this:

error LNK2019: unresolved external symbol main referenced in function __tmainCRTStartup
{project directory}\LIBCMT.lib(crt0.obj)

Why does this work for the x86 build and not the x64 build? Is there something I am missing here?

A: 

This could be a silly question, but are you sure you're linking as a DLL in the x64 case (ie. specifying the /DLL switch) - since the complaint is about main, I wonder whether it's trying to link as a an executable?

RichieHindle
On the "General" tab, I have the configuration type set to "Dynamic Library (.dll)". Is this what you mean?
Jon Tackabury
That does sound right. You should compare the linker command lines of the two targets, via the Linker / Command Line page of the project settings.
RichieHindle
I have compared the command lines, and the only part that's different (apart from the output folders) is the /MACHINE option.
Jon Tackabury
@Jon: ...and be sure to check both the Debug and Release settings for both the x86 and x64 targets. That Project Properties dialog makes it very easy to omit one of those four places when setting things like the Configuration Type.
RichieHindle
I don't even have Debug settings any more, just Release. :) An interesting note, if I use /MD it works fine, but using /MT won't link. I really need to link this statically though to avoid distributing the C++ runtime DLLs.
Jon Tackabury
+1  A: 

Not a direct answer but it may be strictly related: as said in the comment, you should avoid changing the entrypoint in that way: normally the real entrypoint is taken by a "fake" DllMain provided by the CRT to initialize its internal data structures (as explained here), so you're bypassing it. Probably the size reduction is due to CRT init code being removed.

Your dll is working with a non-initialized CRT, which is very bad. You should leave the default entrypoint, which, incidentally, should solve your problem.

By the way, notice that actually you could make a dll without the CRT (and it would become really small), but you shouldn't use the CRT at all, without even linking against it (/NODEFAULTLIB switch). This means that you could just use libraries you explicitly link against (e.g. the Windows API), but I suspect you would lose several C++ features (I think at least exceptions and RTTI).

Matteo Italia
Excellent, thanks for the info!
Jon Tackabury