Link to home
Start Free TrialLog in
Avatar of paulspignon
paulspignon

asked on

nafxcw.lib(appcore.obj) : error LNK2001: unresolved external symbol ___argv

Building a service .exe using Visual Studio 2005 ver 8.0.50727.762. When I try to use MFC static, always get the linker error as in the title. Exactly the same build configuration works fine in 2003 ver 7.1. Of course the problem goes away if I use the option of dynamically linking to MFC dll's, but that can cause problems in deployment.
Avatar of DanRollins
DanRollins
Flag of United States of America image

Nearly all MFC apps use the DLL version of MFC.  It does not need to be distributed because all Windows systems already have it.
Avatar of paulspignon
paulspignon

ASKER

That is dodging the issue, and it's only half true, the runtime modules required depend on the which update of VC++ you build with, I could cite plenty of cases where they are not available. My instatllation script checks for this and sends the user to the Microsoft update site if needed. I would in some cases prefer to deploy a statically linked version
It remains indisputably true that it should be possible to build a statically linked version of my code, only no one seems to know why it doesn't work with Visula Studio  8.0.50727.762.
In other words, my question has not been asnwered.
Indeed, but it's useful to get stuff like that out of the way early (and verify that the Asker is responding :-)

You might find some clues here:

   PRB: MFC and CRT Must Match in debug/release and static/dynamic
   http://support.microsoft.com/default.aspx?scid=kb;en-us;166504

Flyshot: One thing to do is simply add the missing global variable to your own program and see what happens.
Did you create the service project with a static MFC library or did you change it manually later? If the second applies I would recommend creating a new service project (renaming the old one before) and try again.

Another explanation could be that you were linking against a dll which was dynamically linked to MFC. Then, the global objects like __argv might be not properly defined. Note, all global variables which were declared as 'extern' in the header files must have *exactly one* .c or .cpp source where these variables were *defined* by not using the extern keyword. You can search for the sources in the MFC where that happens and might see what preprocessor macros actually prevent that source to be included to your service.
That MS support page only refers to VC++ <= 6.0, I have 8.0, and as I said the same code with the same build config builds just fine in VC++ 7.1. That is the most important point to my mind - why did it used to work but doesn't with the newer VC++?
And of course I have been very careful about using the static cfgs.
__argc and __argv, which get embroidered to the ___ versions, are defined in stdlib.h, no doubt they are defined. What goes wrong is inside nafxcw.lib it would seem (it's naf in VC 8.0?).
Anyhow, just wasted another half a day on this, more urgent tasks piling up, I will have to shelve the issue for now, got a working version deployed with dynamic linkage, will revisit it at a later date.
Thanks all for your responses.

/Paul
Now up to VC9, Visual Studio 2008, the problem remains, cannot build anything with static linkage.
>>>> as I said the same code with the same build config builds just fine in VC++ 7.1
Unfortunately, there are major changes between 7.1 and 8.0. VC7 was made as a successor of the (most popular) VC6.0 and therefore was much nearer to VC6 than VC8. In VC8 they have a completely new STL and of course - as with every new VC version - a new MFC add-on dll which was supposed to add all improvements of MFC to new MFC projects. That add-on now was based on VC7 and not on VC6 what is the major difference. I had made a huge project porting from VC6 to VC8, but actually I don't know exactly what happens if overtaking a a VC7 project which formerly was ported from VC6. Most probably I would experience similar problems than you.

In case the project isn't huge, the following method may be is the easiest way out:

- use VC8 to create a new MFC project with the MFC statically linked.
- Use the same project name but create it at a different location.
- After creation remove all wizard-generated sources from project (deleting them in the project tree).
- maybe beside of stdafx.h and stdafx.cpp in case you work with precoompiled headers
- remove the files from the project folder as well
- copy all sources from the old project (.h, .cpp, .rc, .rc2, .inl,  .hpp) into the new project folder (or into below sub folders accordingly).
- add the files to the project tree and build

>>>> the runtime modules required depend on the which update of VC++ you build with,
Yes, that is why I also use static linking when possible. Nevertheless you also could have a safe dynamic linking. You would have to provide the required MFC redistributable files with your installation. When putting them to your app folder (or to a subfolder), your app would be able to refer to them without spoiling or needing any other client constellation. On VC7 or later and on XP or later you also could use .manifest files (made automatically with your builds if configured) which were located in the apps folder and have all registry information included to run the provided (old) dlls without having them to register at the target system.

Regards, Alex


 
>>>> nafxcw.lib(appcore.obj) : error LNK2001: unresolved external symbol ___argv

The nafxcw.lib and nafxcw.dll was used with statical linking of MFC. It contains that part of MFC that remains in the dll. In order to work properly with the symbols defined in the (static) MFC library, the linking order was crucial. The __argv was the global symbol for the 'argv' argument passed to main function, which was the main entry point for any executable. For dll executables the entry point was DLLMain (usually). In case of a Win32 function the entry point for executables was turned to WinMain but the global variables _argc and _argv  (the linker adds an additional '_') nevertheless must be provided before the nafxcw.lib cause there are functions in that lib wich do refer to them in the interface. In your case it seems that the linker tries to link naxfcw.lib but your the static MFC libraries from VC8 didn't provide the _argv symbol. There can be a few reasons why it didn't work with VC8 though it worked with VC7:

(A) the VC8 would need a furter library to be linked between (static) MFC and nafxcw.lib.
(B) the nafxcw.lib has moved to another position in the linking order because of other issues
(C) the nafxcw.lib was no longer needed by VC8 (or has a different name)

For (A) you might check your linker input configuration if it explicitly refers to nafxcw.lib. I remember that in older VC versions (VC2.1 up to VC6) it sometimes was necessary to explicitly define the linking order which was mostly due by mixing single-threaded and multi-threaded models. E. g. if you use a dll which was build with single-threaded model it needs the single-threaded runtime libraries while in your app which was build as a multi-threaded app was calling multi-threaded runtime library. If in your linker input modules the nafxcw.lib was referenced you *have to* remove all this as you can't expect that to work with newer VC versions (which had to solve much bigger problems when including the dotnet).

(B) and (C) you only can solve with reasonable efforts by creating a new MFC project from scratch as I described above.

Regards, Alex
Maybe you should 'PAQ' the question as there is much information given which may leed to a success in another case.

Regards, Alex
ASKER CERTIFIED SOLUTION
Avatar of Computer101
Computer101
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Resolved. I found that, nevertheless, certain library modules included by the linker had in fact been built for dynamic MFC inclusion, conflicting with the Static linkage requested for the main module.
Hope this can help others to resolve such problems, have seen a number of cries for help like mine.

/Paul