[Comprehensive] tips for compiling and running programs in VC

Source: Internet
Author: User
Tags import database
Document directory
  • 1. Run-Time Library
  • 2. Common compilation Parameters
  • 3. subsystem and executable file startup
  • 4. Do not display the console program in the console window
  • 5. MFC library files
  • 6. Resolution of default library conflicts in VC

In the same title, the content of the two articles is slightly different, so I will combine them.

The following content is from:

Http://blog.163.com/bestfighter_210@126/blog/static/10361887200811206310788/

Http://demon.tw/programming/vc-compile-skill.html

 

1. Run-Time Library

Run-Time library is a standard library provided by the compiler and provides some basic library functions and system calls.
The run-time library we generally use is C run-time libraries. Standard C ++ libraries is also available.
C run-time libraries implements the ansi c standard library. The CRT directory of the VC installation directory contains most of the source code of the C run-time library.

C run-time libraries has a static library version, a dynamic link library version, a single-thread version, a multi-thread version, and a debug and non-debug version.
You can select the run-time Library version in "project"-> "Settings"-> "C/C ++"-> "code generation.

Dynamic Link Library version:
/MD multithreaded DLL import database msvcrt. Lib
/MDD debug multithreaded DLL import data to msvcrtd. Lib

Static library version:
/Ml single-threaded uses static library libc. Lib
/MLD debug single-threaded use static library libcd. Lib
/MT multithreaded uses the static library libcmt. Lib
/MTD debug multithreaded uses the static library libcmtd. Lib

The standard I/o part of the C run-time library is closely related to the operating system. In Windows, the I/O part of the CRT code is only a package, and the underlying function of the operating system kernel kernel32.dll is used, use the import library kernel32.lib during compilation. This is why we generally cannot directly use the C standard library in an embedded environment.

 

2. Common compilation Parameters

When creating a project, VC always defines "Win32 ". The console program defines "_ console", otherwise it defines "_ WINDOWS ". The debug version defines "_ debug" and the release version defines "ndebug"

Compilation constants related to mfc dll include:
_ Windll indicates to create a DLL that uses MFC.
_ Usrdll indicates a user DLL (relative to the MFC extension DLL)
_ Afxdll indicates using the MFC Dynamic Link Library
_ Afxext indicates to create an MFC extension DLL.

Therefore:
Regular, statically linked to MFC _ Windll, _ usrdll
Regular, using the shared mfc dll _ Windll, _ usrdll, _ afxdll
Extension DLL _ Windll, _ afxdll, _ afxext

Cl. EXE compiles all source files, Link. EXE links EXE and DLL, and Lib. EXE generates static libraries.

3. subsystem and executable file startup

You need to specify/subsystem when linking. This link option tells windows how to run executable files.
The console program is/subsystem: "console"
Other programs are generally/subsystem: "Windows"

After selecting subsystem as "console", a console window is generated before Windows enters the executable file code (for example, maincrtstartup.
If "Windows" is selected, the console window is not generated in the operating system. You can create the window for this type of application.

All executable files have an entry point, which can be specified by/entry during link. By default, if the subsystem is "console", the entry point is maincrtstartup (ANSI) or wmaincrtstartuup (UNICODE), that is:
/Subsystem: "console"/entry: "maincrtstartup" (ANSI)
/Subsystem: "console"/entry: "wmaincrtstartuup" (UNICODE)
Maincrtstartup or wmaincrtstartuup will call main or wmain.
It is worth mentioning that before entering the entry point of the application, the Windows loader has initialized the C variable, and the global variables with the initial values have their initial values, variables without initial values are set to 0.

If the subsystem is "Windows", the entry point is winmain (ANSI) or wwinmain (uincode), that is:
/Subsystem: "Windows"/entry: "winmaincrtstartup" (ANSI)
/Sbusystem: "Windows"/entry: "wwinmaincrtstartup" (uincode)
Winmaincrtstartup or wwinmaincrtstartup will call winmain or wwinmain.

These entry-point functions can be seen in the CRT directory. For example, (for simplicity, I deleted some Conditional compilation of the original code ):

void mainCRTStartup(void){        int mainret;        /* Get the full Win32 version */        _osver = GetVersion();        _winminor = (_osver >> 8) & 0x00FF ;        _winmajor = _osver & 0x00FF ;        _winver = (_winmajor << 8) + _winminor;        _osver = (_osver >> 16) & 0x00FFFF ;#ifdef _MT        if ( !_heap_init(1) )               /* initialize heap */#else  /* _MT */        if ( !_heap_init(0) )               /* initialize heap */#endif  /* _MT */            fast_error_exit(_RT_HEAPINIT);  /* write message and die */#ifdef _MT        if( !_mtinit() )                    /* initialize multi-thread */            fast_error_exit(_RT_THREAD);    /* write message and die */#endif  /* _MT */        __try {            _ioinit();                      /* initialize lowio */            _acmdln = (char *)GetCommandLineA();        /* get cmd line info */            _aenvptr = (char *)__crtGetEnvironmentStringsA();        /* get environ info */            _setargv();            _setenvp();            __initenv = _environ;            mainret = main(__argc, __argv, _environ);            exit(mainret);        }        __except ( _XcptFilter(GetExceptionCode(), GetExceptionInformation()) )        {            _exit( GetExceptionCode() );        /* Should never reach here */        } /* end of try - except */}  

If the MFC framework is used, winmain will also be buried in the MFC Library (appmodul. cpp ):

extern "C" int WINAPI_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPTSTR lpCmdLine, int nCmdShow){// call shared/exported WinMainreturn AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);}

For the ANSI version, "_ twinmain" is "winmain"; for the uincode version, "_ twinmain" is "wwinmain ". See afx. h:

#ifdef _UNICODE #define _tmain wmain#define _tWinMain wWinMain#else#define _tmain main#define _tWinMain WinMain#endif

Where is the global C ++ object constructor called? The answer is that after entering the entry point of the application, the initialization operation before the main function is called. Therefore, the theapp constructor of MFC is called before _ twinmain.

4. Do not display the console program in the console window

By default, the/subsystem and/entry switches match, that is:

"Console" corresponds to "maincrtstartup" or "wmaincrtstartup"

"Windows" corresponds to "winmain" or "wwinmain"

We can manually modify the method to make them do not match. For example:

# Include "windows. H"

# Pragma comment (linker, "/subsystem: \" WINDOWS \ "/entry: \" maincrtstartup \ "") // set the entry address

Void main (void)

{

MessageBox (null, "hello", "notice", mb_ OK );

}

This console program will not display the console window. If/MLD is selected, this program only needs to link libcd. Lib user32.lib kernel32.lib.

In fact, if you do not want to see the console window, there is a more direct method: It is to directly change the PE File Header's subsystem from 3 to 2 in the EXE file. In the EXE file, the offset address of the PE file header is 0x3c, the subsystem is a word, and its offset in the PE file header is 0x5c.

5. MFC library files

The Library of MFC can be statically linked or dynamically linked. Static and dynamic libraries can be divided into debug, release, ANSI, and Unicode versions.

Static MFC libraries mainly include:

ANSI debug nafxcwd. Lib

ANSI release nafxcw. Lib

Unicode debug uafxcwd. Lib

Unicode release uafxcw. Lib

Dynamic Link Libraries mainly include;

ANSI debug mfcxxd. Lib (core, mfcxxd. dll ),

Mfcoxxd. Lib (OLE, mfcoxxd. dll ),

Mfcdxxd. Lib (Database, mfcdxxd. dll ),

Mfcnxxd. Lib (Network, mfcnxxd. dll ),

Mfcsxxd. Lib (static)

ANSI release mfcxx. Lib (combined, mfcxx. dll)

Mfcsxx. Lib (static)

Unicode debug mfcxxud. Lib (core, mfcxxud. dll ),

Mfcoxxud. Lib (OLE, mfcoxxud. dll ),

Mfcdxxud. Lib (Database, mfcdxxud. dll ),

Mfcnxxud. Lib (Network, mfcnxxud. dll ),

Mfcsxxud. Lib (static)

Unicode release mfcxxu. dll (combined, mfcxxu. dll ),

Mfcsxxu. Lib (static)

In addition to mfcsxx (D, U, UD). Lib, the above lib files are imported to the database.

The Dynamic Link Library version of MFC also requires static links to some files, which are placed in mfcsxx (D, U, UD). Lib. For example, appmodul. cpp that contains _ twinmain.

6. Resolution of default library conflicts in VC

The VC compiler has two habits when compiling a program:

A. When compiling from the beginning, sort the source file names in alphabetical order and process them in sequence;

B. Compile and decide which default libraries are needed.

These habits sometimes cause strange compilation errors. For example, there are two files in the project:

Charutil. c

Gbnni. cpp

Gbnni. cpp uses the MFC library.

Of course, he handled charutil. C first, and then felt that he needed to link a C Runtime library. He chose libcmtd. Lib based on the project settings.

Then we processed gbnni. cpp again, because we had to use MFC and decided to link nafxcwd. Lib.

At the end of the link, the following conflict occurs:

Nafxcwd. Lib (afxmem. OBJ): Error lnk2005: "Void _ cdecl operator Delete (void *)"(?? 3 @ yaxpax @ Z) already defined in libcmtd. Lib (dbgdel. OBJ)

In fact, if you first link nafxcwd. Lib, there is no need to link libcmtd. Lib, and there will be no conflict.

There are two solutions to this problem.

A. Let the first file of the project contain the header file of MFC, so that the compiler will not find the C Runtime Library. In this way, we need to change the c file to CPP.

B. Change the name of the file that needs to be linked to the C Runtime Library to a greater value, so that it is placed at the end.

It is of course very convenient to use IDE, but since it uses tools written by others, sometimes it has to be considered and adapted to its habits.

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.