PS-Trainer C - Entwicklung
Programm - Flusskontrolle: Bibliotheken
Homepage von PS-Trainer - C-Entwicklung - Flusskontrolle - an PS-Trainer
PS-Trainer PS-Trainer

Program Flow Control Overview of subjects concerning flow control: program start and stop, branching, interation, functions...
Functions Overview of subjects concerning functions
Standard libraries Compiler-provided general libraries
Private libraries Your own libraries containing re-usable functions. You may have programmed these functions by yourself or taken them from the internet, or books, or...
Sharing levels You may share source code, compiled objects or DLL´s
#include The #include directive replaces itself by the contents of the file specified with it.
extern The extern keyword declares a variable or function and specifies that it has external linkage


Standard libraries:

The C compiler´s run-time library provides routines for programming. These routines automate many common programming tasks that are not provided by the C and C++ languages. The libraries themselves have been updated many times, newer and older versions may be incompatible therefore. Some compilers provide options for you to select between different versions of libraries. Consider the most recent version to be used if you do not care about it.

Debug versions:
In most compilers the standard libraries are provided in debug-versions: To build a debug version of your application, the _DEBUG flag must be defined and the application must be linked with a debug version of one of the standard libraries.

Specific versions:
If you can choose between different versions of libraries, select those supporting ANSI (American National Standards Institute) C and UNIX® C specifications, if possible. Other (company-specific or product-specific) versions may offer some benefit for you (ease of use, faster applications) but only ba sacrificing compatibilty and/or portability.

Header files:
contain definitions for global variables, control flags, and standard types used by library routines. Access these variables, flags, and types by including the appropriate header files.

Required and optional header files:
Required header files need to be included to obtain the function declaration for the routine or a definition used by another routine called internally. Optional header files are usually included to take advantage of predefined constants, type definitions, or inline macros.

Library functions:
It is difficult to find overview documentations for standard libraries. Instead, the functions provided (provided by the standard libraries) are well documented and can be found in the compiler help and in the internet. In thsi web, you find a descriptions for selected functions in the library section.


Private libraries:
There is no principal difference between standard and private libraries.
Before writing a library, you should know how to write functions, and how to use them.
If you want to create a private library, start by developing and testing one simple function (you must have at least one properly tested function to start with a library):
Write a program ("main") which calls a function (e.g. "sub00"). Mind: a function should have 3 parts of code: The declaration (usually preceding main, defining the type of the function and of its arguments), the function call (somewhere within main) and the definition (usually after main, which contains the function´s code.
Save the program and its source file for further use. We will refer to this as the all-in-one development-only program.
Transferring the function to a library costs you 2 more statements (#include) to start with, and 1 more statement (extern) for each function added. What you get: forget about all declarations and definitions you have done (once !) in your libray, just use them - the same easy way you use standard functions like printf().
In fact, you only need to separate your all-in-one code into 3 clearly defined parts, and copy the code segments to 3 different files.

Example to create a private library:
Create a new (empty) project
Create a new C++ source file - this will be your "demo file".
Write a main program or copy the main program from your previously created all-in-one test program.
Mind: this file should not contain any other parts of the function but the function call. Delete function declaration and function definition from this file.
Create another C++ source file - your library
Copy declaration and definition of your pre-tested function(s) to this file.
Mind: this file should not contain a main program.
Create a new C++ header file.
Write extern function definitions into this file, one for each function your library provides.
Enter #include directives into both C++ source files, referring to the header file created in the step before.
Compile your main program and test it. Now, if you #include this library into any other projects, you may use all the functions of your private library similarly to the standard functions (e.g. printf), without the need to declare or define them.

Example:
File example content
all_in_one.cpp

(for development only,
not needed later)
#include <stdio.h>
#include <conio.h>

void sub (void);

void main (void) {
printf("\nAll-in-1 test: here is main\n");
sub();
}

void sub (void) {
printf("Here is sub !\n");
}
mylib.h

(#include me to use in your projects)
/*
MYLIB.H
autor, version, date...
*/

#include <stdio.h>

extern void sub (void);
mylib.cpp

(this is the "body" of the library(
/*
MYLIB.CPP
autor, version, date...
*/
#include "mylib.h"

void sub (void);

void sub (void) {
printf("Here is sub !\n");
}
mylib_demo.cpp

(for demo only, but good style to provide together with the library)
/*
MYLIB_DEMO.CPP
autor, version, date...
*/

#include "complex.h"
#include <conio.h>

void main (void) {

printf("\nMylib test: here is main\n");
sub();
}

Mind:
You may also #include other header files (nesting) in your header file, as with <stdio.h> in the example above. In this case, you need not include these files in your main programs. Still, you must #include all other header files you need, as with <conio.h> in the example above.
You may provide any other elements of global interest to your library, such as structure definitions, global constants...
Don´t pack too much overhead in your libraries. It is good style to collect a couple of elements in libraries, which belong to a common group. Rather than adding more and more elements to a library, create new libraries. This is more meaningful and easy to maintain. You may #include several selected libraries into your projects, ready-mixed for the purpose needed, this is just a few #include´s away from you.

Sharing options / levels of libraries:

If you have created re-usable libraries, there are several possibilities to include these in other projects, e.g.:
Sharing Source Code:
Easy to do, but tedious with many projects. High flexibility - you can see the code and you may even change it.

Create a new C++ source file, and copy / paste the lib´s source code into it.
Create a new C++ header file, and copy / paste the lib´s header source code into it.
Create a new C++ source file, write your main program. #Include the header file. Compile and link.

At this level, you may remove all components not necessarily needed, or you may apply some changes to the functions.
If you publish source code, it is clear enough that everyone may use this code without even telling you about. You have created freeware.
Sharing Object level code:
Fast and easy - good for routine work. Object code is what makes the compiler from your source code. You find the *.OBJ files in your workspace environment. The idea is to compile the library only once, as it does not change while you develop your programs. This makes you a lot faster, because usually most of your code comes from libs. Now you need to compile only a small portion of code - the program in development.

Before you start: Find out how your compiler & linker programs handle "import" or "adding" of objects to your project. It is naturally program-dependent how this is done. You will have to add both the header file and the OBJ file from your lib package.
The header file is needed by the compiler (it contains source code, which has to be #Include´d into your program). Once you have got both the header file and your current main code you may compile it - this step produces a new OBJ file of your current project. The compiler does not need your library - it is sufficient to provide extern declarations !
The OBJ file of the library is needed by the linker: This program puts together the OBJ´s of your current program, of your LIB, and of the standard libraries to "link" all these together, in the end resulting in an executable program.
(your compiler certainly has created an OBJ file of your lib while you developed and tested it - you find the OBJ files in your lib-project environment)
You must find out how your compiler allows to add or import other objects, namely object files to your project .
This may be a menu item, e.g. Project - AddTo... , an intelligent workspace manager might recognize by itself that you have added (copied into it) a file, or any other function to provide object import.

Create a new C++ source file, write your main program. #Include the header file.
Add the lib´s object file (*.OBJ) to your project.
You may leave the OBJ file where it is (e.g. in the environment where you have created it) and "link" to it, or you may copy the OBJ file into the current workspace - this step is compiler-dependant.
If you do not find out how it works, try keywords LINK, LINKER, Link OPTIONS, ...
Add the lib´s header file to your project.
If this is not possible, or if you do not find out how it works: create a new C++ header file and copy / paste the lib´s header source code into it. You may even paste the code (e.g. extern function declarations) into another file, e.g. the one containing your main program.
Compile and link your program

This method not only is fast and easy to do, it keeps the "user" developer away from your source code. You may give away or publish lib OBJects which can only be used but not modified. Keep in mind that every program can be hacked and cracked - it only depends on the effort applied. But still publishing an OBJ is an easy and efficient way to protect your work.
Dynamic Link Libraries (DLL´s):
Rather large effort to do. Platform-dependent !!! What you get from your library are not executable programs, but small pieces of code (or data) other programs can load and use at run-time. Creating DLL´s is a science of its own, therefore it is currently not included in this web.

The #include directive
The #include directive tells the preprocessor to treat the contents of a specified file as if those contents had appeared in the source program at the point where the directive appears. You can organize constant and macro definitions into include files and then use #include directives to add these definitions to any source file. Include files are also useful for incorporating declarations of external variables and complex data types. You only need to define and name the types once in an include file created for that purpose.

Syntax
#include "path-spec"
#include <path-spec>


The path-spec is a filename optionally preceded by a directory specification. The filename must name an existing file. The syntax of the path-spec depends on the operating system on which the program is compiled.
Both syntax forms cause replacement of that directive by the entire contents of the specified include file.

The difference between the two forms is the order in which the preprocessor searches for header files when the path is incompletely specified.

Quoted form #include "path-spec"
This form instructs the preprocessor to look for include files in the same directory of the file that contains the #include statement, and then in the directories of whatever files that include (#include) that file. The preprocessor then searches along the path specified by the /I compiler option, then along paths specified by the INCLUDE environment variable.

Angle-bracket form #include <path-spec>
This form instructs the preprocessor to search for include files first along the path specified by the /I compiler option, then along the path specified by the INCLUDE environment variable.

The preprocessor stops searching as soon as it finds a file with the given name. If you specify a complete, unambiguous path specification for the include file between two sets of double quotation marks (" "), the preprocessor searches only that path specification and ignores the standard directories.
If the filename enclosed in double quotation marks is an incomplete path specification, the preprocessor first searches the "parent" file's directory. A parent file is the file containing the #include directive. For example, if you include a file named file2 within a file named file1, file1 is the parent file.

Nesting:
Include files can be "nested"; that is, an #include directive can appear in a file named by another #include directive. For example, file2, above, could include file3. In this case, file1 would still be the parent of file2 but would be the "grandparent" of file3.
When include files are nested, directory searching begins with the directories of the parent file and then proceeds through the directories of any grandparent files. Thus, searching begins relative to the directory containing the source currently being processed. If the file is not found, the search moves to directories specified by the /I compiler option. Finally, the directories specified by the INCLUDE environment variable are searched.

The following example shows file inclusion using angle brackets:
#include <stdio.h>
This example adds the contents of the file named STDIO.H to the source program. The angle brackets cause the preprocessor to search the directories specified by the INCLUDE environment variable for STDIO.H, after searching directories specified by the /I compiler option.

The following example shows file inclusion using the quoted form:
#include "defs.h"
This example adds the contents of the file specified by DEFS.H to the source program. The double quotation marks mean that the preprocessor searches the directory containing the parent source file first.
Nesting of include files can continue up to 10 levels. Once the nested #include is processed, the preprocessor continues to insert the enclosing include file into the original source file.

extern

extern declarator // used when variable or function has external linkage

extern string-literal declarator
// used when linkage conventions of another language are being used for the declarator

extern string-literal { declarator-list }
// used when linkage conventions of another language are being used for the declarators

The extern keyword declares a variable or function and specifies that it has external linkage (its name is visible from files other than the one in which it's defined). When modifying a variable, extern specifies that the variable has static duration (it is allocated when the program begins and deallocated when the program ends).
The variable or function may be defined in another source file, or later in the same file.
In C++, when used with a string, extern specifies that the linkage conventions of another language are being used for the declarator(s).
Declarations of variables and functions at file scope are external by default.
In C++, string-literal is the name of a language. The language specifier "C++" is the default. "C" is the only other language specifier currently supported by Microsoft C/C++. This allows you to use functions or variables defined in a C module.
All of the standard include files use the extern "C" syntax to allow the run-time library functions to be used in C++ programs.

Keywords: auto, register, static, const, and volatile.

Example
The following example declares the functions printf, getchar, and putchar with "C" linkage:
// Example of the extern keyword
extern "C" int printf( const char *, ... );

extern "C"
{
int getchar( void );
int putchar( int );
}


Homepage von PS-Trainer - C-Entwicklung - Flusskontrolle - an PS-Trainer

Aktuelle Daten dieser Seite Letzte Änderung:
  Geocities

 

 

 

Hosted by www.Geocities.ws

1