Embed
Email

ads

Document Sample

Categories
Tags
Stats
views:
8
posted:
11/18/2011
language:
English
pages:
15
Step Two: Link your Program's Components



After the compiler compiles your code, the linker links together the files that make up your

program.

The linker is responsible for combining your compiled code, which may be located in various

files after they are compiled, and connecting the files together, along with any libraries the

program requires. Linking makes sure each piece of code knows how to find the other

elements of your program. For example, the linker modifies the machine code so that your call

to printf() gets correctly routed to the MSL library function printf(), which does the all of the

magic necessary to implement console I/O.

When you write a program, you split your code into functions that are stored in different files

and are compiled to a single output file. In the case of the Hello World program I've been using

as an example, this output file is an application. In some cases, functions used in a program

may not even be stored in the same output file. When would this happen? When you write an

application, for example, that contains a lot of code that is reused in several parts of your

program, you might compile all of that reusable code into a single shared DLL. When you do

this, the application can still access the code, but it needs to know where and how to find it

when it needs it, hence the need for linking.

Types of Linking

In programming, a link is a pointer, either to an object, such as a compiled function, or to data,

such as a variable or an array. There are two ways to link: hard linking and soft linking.

Hard linking occurs when all of the code is accounted for at link time. That is, if a function is

used, the linker knows exactly where it is at link time and can create a direct link to it.

Soft linking (also known as weak linking) is when some of the code may not be accounted for

at link time, but you know that it is in a DLL that will be accessible at runtime. In this case, the

linker can tell your application to search for the DLL when it is needed.

Soft linking is the method used by many elements of your computer's operating system. Next,

we'll take a look at some of the options that the linker provides.





A Detailed Look at Linking



To further appreciate the functionality of the CodeWarrior linker for the Windows platform, you

need to understand how you can configure the CodeWarrior linker to accomplish what you

need.

Configure the Linker to Suit your Needs

The choices in this lesson appear in the x86 version of the CodeWarrior linker panel (Figure

4-1). But many of the terms used in the x86 linker are applicable to other linkers.









1

Figure. 4-1 The x86 linker settings window.



Open the Settings window by choosing "Project Name" Settings from the Edit menu.

(Project_Name is the currently active project -- in this case, Hello World x86.) Click on the x86

Linker (or similar) tab in the Settings window.

Let's take a look at some of the linker options:





 Entry Point Usage: Under the Windows OS architecture, each code module has a

number of entry points that may or may not be optional, depending on the type of code

you are building. The nature of these entry points depends upon the type of output file

you're making (application, library, or DLL) and other factors. The host OS uses this

entry point information to properly call a DLL's initialization functions when an

application demands its services. Most often, you will leave this set to Default as

shown in Figure 4-1. This lets CodeWarrior automatically set up the proper entry

points for the output file, based upon your choice of target in the x86 Target panel.

 Subsystem: There are several settings here. Of interest to you are the Native,

Windows CUI, and Windows GUI selections. The Native setting is for building drivers

and other exotic system modules. The Windows CUI setting is for those applications

sporting a console-style user interface (hence the name CUI). The Windows GUI

choice supports applications that rely on the Windows graphic user interface (GUI).

You'll notice that our simple, console-based Windows application uses the CUI

subsystem, as expected. Normally, CodeWarrior sets the subsystem for you

automatically when you choose a CodeWarrior project template to construct the

project file.





2

 Subsystem ID/UserID: Like the subsystem item, this item is typically set for you

automatically. For the curious: Windows 3.1, Windows 95, and Windows NT 3.5 have

an ID of 3.10, while Windows NT 4 has an ID of 4.00.

 Generate Link Map: This option allows you to generate a text file that contains

detailed information on the classes and functions used throughout your program. This

can be extremely helpful when debugging code by matching addresses to variable or

function names.

 Generate SYM File: This option allows you to generate a symbol file during the link

process. Most debuggers require a symbol file in order to step through your source

code when debugging. This is discussed in more detail in Lesson 5. You can also

generate a symbol file for CodeView, a popular Windows debugging tool, by checking

the Generate CV Info item.

 Generate CV Info: Generates a symbol file for CodeView, a popular Windows

debugging tool.

 Command File: This item lets you pick the name of an optional text file that directs

sophisticated linking options. Called the linker command file, you use it to specify

which symbols to import and export, and other advanced linking operations. Unless

you're writing special-purpose code, you won't normally need a linker command file.



As you can see, the linker can be a relatively complex piece of software machinery. Luckily, in

many cases, the default settings will suffice. Very rarely will you have to tweak the linker

settings to get your programs to work. The folks at Metrowerks have done an excellent job of

managing this thankless job for you. Yay, CodeWarrior!





An Introduction to Debugging



Purging pesky pests proves productive for programmers!



Debugging is the process of tracking down a problem in your code and fixing it. The sad truth

is there is always the possibility that your code contains typing or logic errors. Maybe you

thought through a problem thoroughly but still missed a key step in solving it, or maybe you

made a tiny typo in your code or used the wrong variable. In many cases, you'll know when

you have a flaw in your logic or a programming error because your program will not function as

expected. Or, in a worst-case scenario, your computer will crash. When this happens, it's time

to begin debugging.

CodeWarrior includes an integrated debugger, which just means that you can view it while

you're looking at other windows of CodeWarrior. Begin using the debugger by selecting Enable

Debugger from the Project menu; then rebuild your target. Once that's done, your program will

run within the debugger window, allowing you to isolate and fix any problems you find.

Quite often you will generate a debug target of the program. The target's source files remain

the same, but many of the options required to produce a debuggable version of the program

(such as generating a symbol file) are preset. This lets you flip into debug mode by just picking

the debug target from the Project window's pop-up menu.









3

Figure 5-1: The debugger does its thing.



Figure 5-1 shows the Hello World debug program running within the CodeWarrior debugger.

Note that we've added a few lines of code to the program in the form of a loop using the

variables i, x, and y. We added this code in order to more easily demonstrate how the

debugger works. The debugger allows you to step through your code line by line. As you move

through the code, you can also note the values of all of your variables. By forcing your program

to run in this "slow motion" mode, you can see exactly how your code is working and very

easily track down bugs.



I lied. Not all bugs are easy to track down. I've personally worked on bugs that

have taken weeks to figure out and fix. Anyone who has programmed for any

length of time probably has similar horror stories. Don't let them get you down.

On top of everything else, you are a beginner, so you will inevitably be writing

buggy code. Remember: we learn more from our mistakes than our

successes. OK, I'll stop now.



Notice the buttons at the top left corner of the debugger window. These buttons assist you in

stepping through your code. The buttons are, from left to right: Run Program, Stop, Kill (Quit),

Step Over, Step Into, and Step Out. The last two step commands allow you to decide whether

you want to step into a particular function in your code, or simply step over it and let the entire





4

function execute in one fell swoop. If you know that a certain function does not contain the bug,

you can easily step over it and save time. If you're not sure, you can step into it and walk

through its code line by line. As a beginner, you should assume that nothing is bug-free -- and

you can use the practice.

The Debugging window (Figure 5-1) contains three main sections:





 The Stack pane (top left) contains a display of the call stack, also known as call

history. As you step through source code and call function after function, this area

displays the history of functions you have called to get to the current location. This list

grows and shrinks as you step through different sections of a program and according

to whether you step into functions or not.

 The Variables pane (top right) shows variable names and their values. Depending on

the type of variable, this display will vary to allow you to view (and edit) the data

accordingly. In the case of the Hello World x86 program, shown in Figure 5-1, there

are four variables: c, i, x, and y. As you step through your code, the values of the

variables will update in this window in real time. For example, notice how the latter

three variables have realistic values (since these values were set by the code loop),

while c has a nonsense value (you have yet to enter a character into the getchar()

function). Using this pane to spot odd or unexpected values is one of the keys to your

debugging success.

 The Source pane (bottom) displays the C source code for Hello World x86 program. It

can also display the assembly language version of the code. Depending on the type of

bug you are tracking down, the C source display may not provide enough detail. In that

case, you may need to view the program at a finer level of detail -- in assembly

language. The pop-up menu at the bottom of this window lets you choose whether you

view the program as source, assembly language, or a mix of the two.



Note the red stop sign on the left edge of the Source pane. The stop sign indicates a

breakpoint. You set breakpoints in the debugger to tell it where to stop executing your code.

This feature can come in very handy when you want to quickly move to a certain point in your

program and begin working from there. When you set a breakpoint, the debugger will

automatically stop at that line of code and will let you take control. The small blue arrow is the

current program counter; it points to the line of code that is about to be executed. In the Figure

5-1, we have set the breakpoint so that the program executes the code loop before halting on

the second printf() statement. You can set and clear breakpoints by simply clicking to the left of

the line of code you're interested in.

Let's look at some of the preferences for the CodeWarrior debugger.





Global Debugger Preferences



There are many global preferences in the CodeWarrior debugger. Let's take a look. These

settings can be reached by selecting Preferences from the Edit menu.

Display Settings







5

Figure 5-2: Display settings.



The Display Settings panel (Figure 5-2) contains preferences that determine how the

debugger displays information in its windows. As you begin to use the debugger, you will find

that you want certain text to appear larger or smaller, or to be displayed in a specific color. You

can select these options here.

Color settings allow you to choose the text color used by watchpoints or variable names when

the code alters them. This allows you to see if a watchpoint or variable is being changed

without your knowledge as the code executes. Watchpoints are useful if you want to track a

variable at intervals throughout the program and want it to be conveniently displayed in a

window.

The other settings are self-explanatory. In most cases, the default settings will work. As you

learn more about the debugger, you may want to alter these settings.

Windowing Settings









6

Figure 5-3: Windowing Settings.



When debugging, you will quickly find that your desktop is cluttered with lots of open windows.

The Windowing settings (Figure 5-3) allow you to manage windows by choosing to hide or

show certain types of windows when you start debugging. The default setting, Hide

Non-Debugging Windows, will probably suffice in most cases.









Global SettingsThe Global Settings pane (Figure 5-4) contains options that control the way the

debugger operates.







7

Figure 5-4: Global settings.



Cache Edited Files Between Debug Sessions setting allows you to choose how long to cache

edited files between debug sessions. Caching files can increase the speed of the debugger but

will also take up precious disk space.

The remaining settings are self-explanatory. The default settings will serve you well as you

begin to use the debugger.

Remote Connections









Figure 5-5: Remote Connections.



Lastly, the Remote Connections Settings (Figure 5-5) allow you to remotely debug code

across a TCP/IP network. These settings are advanced, and the default values will work fine

as you learn to debug in CodeWarrior.

Note that the Java Settings and Java Debugging panels are for the Java Programming

Language and are not covered in this course. However, other courses are available for this

language!





Target and Project-Specific Debugger Preferences



The following settings are specific to each target and project that is debugged. You can reach

them by selecting Project Name Settings from the Edit menu, while a target is selected in the

Target tab in the CodeWarrior Project window.









8

Figure 5-6: Target and Project Debugger Settings.



Debugger Settings



 Location of Relocated Libraries, etc: If the file you are debugging has been moved, or

if you're debugging remotely over a TCP/IP network, you must type the file's directory

path into this text box.

 Stop at temp breakpoint on application launch: By default, this option breaks the

debugger (stops execution of the code) at the beginning of your program. However,

you can choose to break at any point.

 Auto-target Libraries: Check this setting to automatically access libraries. This can

assist you when debugging code that is part of a library. The debugger will "do the

right thing" (such as loading the library and calling any initialization functions) as you

step into its code.

 Log System Messages: This setting forces all system messages to be written to a log

file. This can be useful if your code is crashing your computer, and you can't see the

screen during the crash. The messages will be written to a log file that you can view

after you restart your computer. Log files can save you many headaches later. Learn

to read them!

 Data Update Interval: By setting a value here and checking this box, you can choose

how often data views are updated. The more often you update data views, the more

up-to-date the displayed values will be in the debugger.

 Cache symbolics between runs: Symbolic files (files generated during the compile

process) will be cached and referenced between debugger runs. This can speed up





9

the debugging process.

 Stop at Watchpoints: To stop at watchpoints when they are equal to true, check this

option. Watchpoints can be very useful, similar to breakpoints. Whereas a breakpoint

will break into the debugger on a specific line of code every time, a watchpoint

monitors a variable or area of memory and breaks into the debugger only when the

contents change. There is also a feature called a conditional breakpoint that will halt

execution when the condition is true. Depending on your needs and the way you like

to work, these advanced features can be very helpful to you as a programmer.





x86 Exceptions









Figure 5-7: The x86 Exceptions panel.



As you debug questionable code, the CodeWarrior debugger intercepts certain oddball

operations (termed exceptions) brought about by a program bug. The IDE passes these

exceptions along to special code -- appropriately known as a handler -- that attempts to deal

with the problem gracefully.

However, for many exceptions, the debugger simply stays out of the way. Why is this?

If you're doing advanced programming such as writing a system library or a device driver, you

may want to test how its code handles some of these exceptions. By not intercepting many

exceptions, the debugger lets you do this. If for some reason you want the debugger to "seize

control of the moment" for specific exceptions, you can direct it to do so with this panel. The

exceptions shown here are ones that the CodeWarrior IDE is prepared to handle. Click on the

exception types you need the debugger to field for you, and then click Save. As mentioned

previously, this is heavy-duty programming material, so we won't go into any details here. The





10

debugger is a very advanced, yet very easy-to-use addition to the CodeWarrior environment. If

you learn to use it well, it will become one of the most important tools in your software

development arsenal.

Note that the Other Executables and Remote Debugging panels are for advanced users and

are not covered in this course. If you ever have a need to debug multiple-executables at a time

and/or debug over a TCP/IP network, you will know it!







Libraries



What's a library? This is a question you need to know the answer to! A library is a file that

contains compiled code that your programs can call upon when needed. Typical functions that

libraries can offer are file and screen I/O, memory management services, 3-D graphics display,

and scientific computations. Libraries can save you time in the development process and help

simplify your software applications. Chances are that you will use libraries quite often in

developing programs. There are several ways to use library code in your programs:





 Write it yourself in a source code file, and optionally compile it as a library or DLL.

 Use a library provided by someone else.

 Use a shared library (a DLL) provided by someone else.





Writing Your Own Library or DLL

The first method is simple. When you include code within a C or C++ source file, you complete

the program by simply compiling, linking, and executing it. This is the way we've been working

thus far during this course. See, you were using them and you didn't even know it. You're

good.

Using Someone Else's Library

Using someone else's library changes things a bit. Libraries provided by third-party vendors

contain several files: the library file itself (usually with a name ending in .lib), a header file (.h),

and (hopefully) some documentation (.doc). The header file is required so that the compiler

can match function calls in your program to functions within the library. You include the header

file in your source file and then simply call the library functions as if they were part of the

operating system. In most cases, you place the .h and .lib files in your source path, as defined

by CodeWarrior. This path is usually in the directory where your project file is located, or inside

a subdirectory of this directory. Note that certain libraries CodeWarrior provides, such as its

MSL, reside in a different directory from the one your project lives in. In fact, CodeWarrior has

its own special access paths, called system paths, which point to the directories of its own

libraries and header files.

Using a Shared Library

Third-party vendors ship library files with their products so that they don't have to part with their

source code. If you're the vendor, it's much safer to include the library and a header file (as

opposed to a C or C++ source file and a header file), especially if you want to protect your

intellectual property. The problem with this approach is that if there's a bug in the library you've

gotten from a third-party vendor, you'll be unable to fix it yourself. You'll have to obtain a fix for

the library from that vendor, and who knows how easy that will be?



11

Sharing DLLs

A DLL is very similar to a library file. In fact, the only difference is that a library file usually gets

compiled and linked into your application, while a DLL is a separate file that either sits in your

system directory or in the same directory as your compiled application. When your application

runs, it locates the DLL and uses its services on the fly. DLLs are typically identified by the .dll

extension.

Benefits of Sharing DLLs

The benefit of a DLL is that it can be shared. OK, that was pretty obvious. What is the benefit

of sharing? First, more than one application can make use of a DLL. This can be especially

useful when several programs use a large DLL that takes up lots of disk space and/or memory.

Also, if a DLL contains a bug and is updated, all programs that share it will be automatically

updated. This saves you and your run-time processing large amounts of time. So what kind of

library would need to be shared by multiple applications? Oh, stuff like the very windows you

see in your operating system environment.

Note on Using Shared DLL files

The CodeWarrior IDE CD-ROM contains dozens of libraries, and hundreds more are available

on the Internet. Always, always, always run a virus check or disinfectant program before

incorporating third party code into your product. It's a good habit, like locking the door every

time you leave the house.

The libraries included with CodeWarrior fall into two categories. The first is the MSL, which

provides ANSI C/C++ standard functions. The MSL has been ported to many platforms, so its

functions are available in various flavors of Windows, the Mac OS, and Solaris. A second set

of libraries is intended for platform-specific uses. For example, on the Windows CD, you'll find

Windows 32 support libraries that interface to the Windows APIs and the MFC libraries, which

provide an object-oriented application framework for writing Windows applications. When you

gain more programming experience, you will find more uses for the specialized libraries.





What is MFC?



The Microsoft Foundation Classes (MFC) provides a set of functions that let you quickly write

Windows applications. While you're free to call the Win32 APIs directly, it's easier to use the

MFC because the classes provide basic services such as creating a window or writing a file

along with intelligent default settings and error-checking code. MFC is available on the

Windows CodeWarrior CD but may not be the very latest version of the classes. Check with

the Metrowerks help desk for that information, as Microsoft will send update patches between

CodeWarrior releases.

For the sake of platform parity, Macintosh developers can use Metrowerks' own PowerPlant

class libraries. PowerPlant is an object-oriented application framework designed for writing

Mac applications. Although we will not discuss PowerPlant here, it and MFC are similar in

many ways, and what you learn here will help you to understand PowerPlant as well. When I

discuss MFC, it is safe to assume that the same concepts apply to PowerPlant.



Note: There is also a library version of MFC on the CodeWarrior Macintosh

CD, but unlike the Windows CD, the source code is not included for the

Macintosh. Using MFC, you can write cross-platform code. Once you have



12

written the code, you can compile it for both the Macintosh (using PowerPlant)

and the PC (using MFC) at one time. Pretty cool, huh?





Application Framework

As mentioned earlier, MFC is an application framework. This means that MFC is a collection of

C++ classes in source code or library format. The framework can create a complete

application that supports advanced operating system features in a fraction of the time it would

take to do it all by hand. Note also that MFC contains tools to facilitate building your user

interface. These tools, specifically the Image Editor, Dialog Editor, and Resource Compiler,

help you build the graphic elements of the user interface (the last section of the lesson

explains how to install these useful components). An application framework concerns itself

primarily with the standard user interface of the application, as opposed to the specific content

of the application. Put another way, the framework helps you build a robust application

interface to interact with the user, giving you more time to write the other functions that

implement the application's purpose. So you don't have to worry about spending time and

energy coding a scroll bar or close box from scratch to appear like all other applications

running in the operating system environment. You can just use the libraries and get on with the

real creative stuff.









Figure 7-1 MFC's user interface builder.



Application frameworks also handle the dispatching of messages (such as user keystrokes,

mouse clicks, drawing messages, etc.) to the many buttons, lists, windows, and controls in

your application. This allows you to keep your application's code focused on its own features





13

rather than on addressing interface questions like "How do I tell when the user pressed the

Enter key?" or "How do I know when I need to redraw the contents of a window?" It's really the

little things that mean the most once you are actually using the application.

Application frameworks provide many benefits over the old-style roll-your-own approach. For

one thing, the code is mature and well tested. Hundreds of applications are being built by

hundreds of developers using MFC every single day. It is constantly being updated as new

features are added to the Windows operating system. In many cases, you can recompile your

application with a new version of MFC and take advantage of all the new features with few if

any changes to your source code.

Application frameworks also provide reusable code. Code reuse is one of the main reasons

object-oriented coding methodologies like C++ were developed. By writing code in reusable

classes, you can easily build upon existing classes to add necessary features. Code reuse

allows you to depend on well-tested code throughout your application and feel confident that

the code will work as expected. It is also very easy to share classes that you build with others

who may need the same features.

Application frameworks can sometimes make your programs a bit larger than they might be if

you were to create them completely from scratch. Since modern computers are usually

equipped with substantial amounts of memory, and since the framework can be used as a DLL,

it's fairly easy to justify the added bulk. PowerPlant and MFC are both very powerful tools that

you should consider using.

Your best bet now is to focus on learning more about MFC and how it can assist you -- and you

can make the decision on how much you want done for you, or how much you want to dig in

and do yourself.

How to Install and Use MFC Interface Tools

The MFC interface tools (including Dialog Editor and Image Editor) are located on the

CodeWarrior CD. Unfortunately, they're not part of the CodeWarrior Installation, so after the

initial CodeWarrior installation, you won't find them on your hard drive. In order to install the

tools, simply perform the following steps:





 You need to locate the file named iTOOLS.Exe. This is the installation program you

will use to install the MFC Interface Tools. The iTools.Exe file should be located at

C:\Program Files\Metrowerks\CodeWarrior\BinSDK\bin\. If you can't find the file there,

then go to the CodeWarrior CD. The file iTOOLS.Exe can be located in the folder

Extras\SKDs\Win32\Microsoft Win32 SDK Tools\.



Note: The Installation program (iTOOLS.Exe) will ask you where you want to

save the MFC Interface Tools. Unfortunately, there is no Browse button to

locate a folder location, so you will have to manually type in a directory path. If

you are unsure of the exact path for where you want to save the tools, locate a

file that resides in the folder where you want to save the tools and retrieve the

complete path for this folder by examining the file's properties (right-click on

the file and select Properties). Here's a quick tip: you can actually copy the

path from this Properties box and then paste the path when prompted by the

installation program.





14

 The tools will be located in the \bin\ folder of the target installation folder. The \bin\

folder is where you'll find the Dialog Editor (DlgEdit.Exe), Image Editor (ImagEdit.Exe),

and other useful tools.

 If you're developing applications for Windows 95 or Windows NT, the necessary tools

are available in the folders \bin\win95 and \bin\winnt, respectively.









15



Related docs
Other docs by Stariya Js @ B...
Lab2_Fishing_lab_pack
Views: 0  |  Downloads: 0
JMK sample legal brief
Views: 1  |  Downloads: 0
DriveQ
Views: 0  |  Downloads: 0
cybersecurity_reform_-_senate_bill_eyes
Views: 0  |  Downloads: 0
Opening and Marketing
Views: 0  |  Downloads: 0
Making_it_Work_notes
Views: 0  |  Downloads: 0
First Announcement 7th ISFS_
Views: 0  |  Downloads: 0
as90173
Views: 0  |  Downloads: 0
VNAfashionshow2010
Views: 0  |  Downloads: 0
By registering with docstoc.com you agree to our
privacy policy

You are almost ready to download!

You are almost ready to download!