2.3 Microsoft eMbedded Visual C++
Microsoft® eMbedded Visual C++ is a member of the Microsoft eMbedded Visual Tools 3.0 family of products which also has eMbedded Visual Basic. These products provide complete integrated development environments for creating applications to run on the Windows CE operating system.
2.3.1 Introduction
Microsoft® eMbedded Visual C++ enables programmers to develop Windows CE-based applications using an integrated development environment (IDE) similar to that used in developing desktop Visual C++ applications. This IDE, however, contains Windows CE-specific versions of many of the standard development tools that are used to create, test, and refine applications. It also includes a variety of tools that can be used to develop new software uniquely appropriate for Windows CE platforms and devices.
Custom-built for developing Windows CE applications, the eMbedded Visual C++ IDE is easy to learn and will be familiar to programmers who have experience with other members of the Visual C++ family. Applications can be created with eMbedded Visual C++ to run on the Handheld PC Pro (H/PC Pro), Palm-size PC 1.2, and Pocket PC platforms. The developers can also use eMbedded Visual C++ to create applications that run on custom Windows CE-based platforms, or within a desktop emulator that simulates a Windows-CE based platform. Embedded Shruti is coded using eMbedded Visual C++ for Pocket PC platform and tested on the Pocket PC emulator.
2.3.2 Managing Projects and Workspaces
In eMbedded Visual C++, applications are developed in a Workspace. Applications by assembled by either creating a project and a workspace simultaneously or by creating a workspace and then adding projects to it. After a workspace is created, the developer can add new projects, new configurations to an existing project, and subprojects. Microsoft eMbedded C++ development is characterized hierarchically by the workspace, projects, and subprojects.
-
A workspace is a container for the development projects. When a new platform is created, a workspace is also created. Use Project view to look at and gain access to the various elements of projects. A workspace can contain multiple projects, including subprojects, but only one platform.
-
A project is a configuration and a group of files that produce an application or final binary file(s).
-
A subproject is a project that is dependent on another project. This dependency may consist of shared files, which need to be built in the subproject first, or it may include shared resources that need updating in the subproject first.
2.3.3 Developing an Application
After initially creating a project, developer can create the user interface. This involves first designing and creating dialog boxes, menus, toolbars, accelerators, and other visual and interactive elements, and then hooking them up to code. The user interface elements have to be tailored to the design requirements of the target device. For example, the Pocket PC is long and narrow (about 240x320 pixels), while the Handheld PC is larger (about 640x320 pixels). If the application is designed for the Pocket PC, dialogs will likely be too small for the Handheld PC. If the dialogs are designed for the Handheld PC, they will likely be cramped or not fit at all on the Pocket PC.
2.3.4 Building an Application
Microsoft eMbedded Visual C++ provides two ways of building an application. The easiest and most common way is to build within the eMbedded Visual C++ development environment. The other way is to build from the MS-DOS prompt using command-line tools. Building an application involves the preprocessor, the compiler, and the linker.
-
The preprocessor prepares source files for the compiler by translating macros, operators, and directives.
-
The compiler creates an object file containing machine code, linker directives, sections, external references, and function/data names.
-
The linker combines code from the object files created by the compiler and from statically-linked libraries, resolves the name references, and creates an executable file.
2.3.5 The Build Process
The following diagram shows the components of the build process in eMbedded Visual C++ starting with the editor which can be used to write source code.
If the program is built outside the IDE, the developer may use a makefile to invoke the command-line tools. Microsoft eMbedded Visual C++ provides the NMAKE utility for processing makefiles. If the program is built within the IDE, the eMbedded Visual C++ project system uses the project (.vcp) files to store make information. The .vcp files are not compatible with NMAKE. However, if the program uses a makefile rather than a .vcp file, it can still be built in the development environment as an external project.
2.3.6 Testing and debugging an application
Microsoft eMbedded Visual C++ provides tools to help test and debug applications. In the eMbedded Visual C++ options, the developer can choose to automatically or manually download the programs after building them to a connected device. When the developer has completed building a project configuration, the program can be run in eMbedded Visual C++ with or without debugging capabilities provided by the IDE. Running programs without using the debugging capabilities is faster because eMbedded Visual C++ does not have to load the debugger first. With the debugger however, breakpoints can be used and step through execution, inspect memory and registry values, check variables, observe message traffic and generally examine closely how the code works.
2.3.7 MFC for Windows CE
The Microsoft® Foundation Class (MFC) library for the Windows® CE operating system is both a mature, comprehensive class library and a complete object-oriented application framework designed to help the developer build applications, components, and controls for Windows CE-based platforms. The developer can use the Microsoft Foundation Classes for Windows CE to create anything from a simple dialog box-based application to a sophisticated application that employs the full MFC document/view architecture. MFC can also be used for Windows CE to create full-featured Microsoft® ActiveX® controls and ActiveX containers.
The developers who have experience using MFC for desktop applications will find MFC for Windows CE very similar and the migration to MFC for Windows CE will be smooth.
MFC supports a number of classes to help the developers write applications using those utility classes. For example if the developer wants to use a hash data structure then there is no need to design the data structure from scratch. Instead the developer can use a CMap class already defined in MFC and the application will be made quite fast.
Microsoft Foundation Classes provides a framework of a number of utility classes and provides the developer with a number of programming options.
Microsoft® eMbedded Visual C++® 3.0 toolkits contain all the development tools and wizards needed for building MFC for Windows CE applications. Several MFC classes are used in the design of Embedded Shruti and the details of the classes will be provided in Chapter 4 which explains the design of Embedded Shruti.
2.4 Microsoft SQL server CE
During the development phase of Embedded Shruti, Microsoft SQL server for CE was considered as an option for providing database support to the application. This section will explain some of the key features of the Microsoft SQL server CE and the reason why it was not used in Embedded Shruti.
2.4.1 Rapid Application Development
SQL Server CE makes application development easy while providing a consistent development model and API set. Microsoft® Visual Basic® developers can rapidly develop Windows CE applications by using eMbedded Visual Basic and ADOCE (ActiveX data objects from Windows CE). Microsoft® Visual C++® developers can leverage their existing skills to build sophisticated Windows CE-based database applications that target mobile and embedded solutions.
2.4.2 High-Performance Database Engine
SQL Server CE offers rich relational database functionality in the small memory footprint on today's devices. Microsoft SQL Server developers will appreciate the robust feature set which includes:
-
A compatible SQL grammar with SQL Server 2000. Statements that run on SQL Server CE will, in general, run on SQL Server.
-
A wide range of data types, including:
-
TINYINT, SMALLINT, INTEGER, BIGINT
-
REAL, NUMERIC, FLOAT
-
BIT, BINARY, VARBINARY, IMAGE
-
UNICODE character data types NATIONAL CHARACTER, NATIONAL CHARACTER VARYING, NTEXT
-
MONEY, DATETIME, UNIQUEIDENTIFIER
-
32 indexes per table, multicolumn indexes
-
NULL support
-
Nested transactions
-
128-bit file level encryption
-
DDL: Create databases, alter tables, referential integrity, default values
-
DML: INSERT, UPDATE, DELETE
-
SELECT: SET Functions (aggregates), INNER/OUTER JOIN, subselect, GROUP BY/HAVING
-
Scrollable and forward-only cursors
Hardware and Software Requirements
Hardware Requirements
Platform
|
Requirements
|
SQL Server system
|
See the operating system requirements in SQL Server Books Online.
|
IIS system
|
120 MB of available disk space.
|
Development system
|
30 MB of available disk space. The computer will need an additional 30 MB of temporary storage space for the setup files.
|
Windows CE device
|
Between 1 and 3 MB of available storage space, depending on processor type and components installed.
The file sizes for the SQL Server CE components vary by processor type and Windows CE operating system version. Hard disk space requirements also depend on which SQL Server CE components are installed.
|
Operating System Requirements
Platform
|
Supported operating systems
|
SQL Server system
|
See the operating system requirements in the SQL Server Books Online.
|
Development system
|
Microsoft Windows 98 Second Edition, Microsoft Windows Millennium (Me), Microsoft Windows NT® 4.0 with Service Pack 5 or later, or Microsoft Windows 2000.
Windows CE desktop emulation requires Windows NT 4.0 or Windows 2000. Emulation is not supported on Windows 98.
Microsoft ActiveSync 3.1 or later.
|
IIS system
|
Windows NT 4.0 with Service Pack 5 or later, or Windows 2000.
|
Windows CE device
|
Windows CE version 2.11 or later.
|
SQL Server Requirements
SQL Server
|
Supported SQL Server CE features
|
SQL Server 2000
|
All features are supported including merge replication and RDA.
|
SQL Server version 6.5 with Service Pack 5 or later and SQL Server 7.0
|
RDA is supported; replication is not supported.
|
Internet Information Services and Internet Explorer Requirements
Component
|
Requirements
|
Microsoft Internet Explorer 5.0
|
Internet Explorer 5.0 or later is required on the development system to access SQL Server CE HTML Help.
Internet Explorer 5.0 or later is required on IIS system.
|
IIS
|
Replication and RDA require IIS 4.0 on Windows NT 4.0 or IIS 5.0 on Windows 2000.
|
ActiveSync Requirements
Component
|
Requirements
|
SSCERelay.exe
|
Windows 98 Second Edition, Windows Millennium (Me), Windows NT 4.0 with Service Pack 5 or later, or Windows 2000.
|
Windows CE Requirements
Platform
|
Windows CE operating system version
|
Handheld PC Pro (H/PC Pro)
|
2.11 or later
|
Palm-size PC (P/PC)
|
2.11 or later
|
Pocket PC
|
3.0 or later
|
HPC 2000
|
3.0 or later*
|
2.4.3 Drawbacks of SQL server (Windows CE version)
The tables showed above gives a complete reference to the hardware and software requirements for SQL server for CE. Take a look at the Windows CE device requirement. Depending on the processor type and components installed, 1 MB to 3 MB of storage space is required on the Windows CE device.
On the top of that Embedded Shruti doesn’t need a database that supports extensible set of SQL statements. Queries are made only by sending a key rather than writing the SQL statements. Keeping this design issue in mind, using SQL server for Windows CE will just eat up the resources while not producing any significant gain. For an embedded application 1 MB space (minimal Windows CE installation) is quite large. The application needed an extendible hashing based database which would save the database values according to the key field and then retrieve the values efficiently. Extendible hashing is an efficient implementation since retrieval is having a complexity of O (1+alpha) where alpha is the load factor. For balanced hash tables the retrieval will give better performance than SQL server for Windows CE which have to process the SQL queries involving extra overhead. A well known hash based database called GDBM which is quite popular on UNIX platform is ported on Windows CE platform and used in Embedded Shruti. Thus Embedded Shruti uses a variant of GNU software and thus is a merger of Microsoft technologies and Open source GDBM project.
The next section will introduce the GDBM (GNU Database Manager) in general.
2.5 GNU Database Manager (popularly called GDBM)
GDBM - The GNU database manager is a set of database routines that use extensible hashing.
2.5.1 Synopsis
#include // This file contains all the function and data type definitions for
// GDBM
extern gdbm_error
gdbm_errno
extern char
*gdbm_version
GDBM_FILE
gdbm_open (name, block_size, read_write, mode, fatal_func)
char * name;
int block_size, read_write, mode;
void (*fatal_func) ();
void
gdbm_close (dbf)
GDBM_FILE dbf;
int
gdbm_store (dbf, key, content, flag)
GDBM_FILE dbf;
datum key, content;
int flag;
datum
gdbm_fetch (dbf, key)
GDBM_FILE dbf;
datum key;
int
gdbm_delete (dbf, key)
GDBM_FILE dbf;
datum key;
datum
gdbm_firstkey (dbf)
GDBM_FILE dbf;
datum
gdbm_nextkey (dbf, key)
GDBM_FILE dbf;
datum key;
int
gdbm_reorganize (dbf)
GDBM_FILE dbf;
void
gdbm_sync (dbf)
GDBM_FILE dbf;
int
gdbm_exists (dbf, key)
GDBM_FILE dbf;
datum key;
char *
gdbm_strerror (errno)
gdbm_error errno;
int
gdbm_setopt (dbf, option, value, size)
GDBM_FILE dbf;
int option;
int *value;
int size;
2.5.2 Description
GNU dbm is a library of routines that manages data files that contain key/data pairs. The access provided is that of storing, retrieval, and deletion by key and a non-sorted traversal of all keys. A process is allowed to use multiple data files at the same time.
A process that opens a gdbm file is designated as a "reader" or a "writer". Only one writer may open a gdbm file and many readers may open the file. Readers and writers can not open the gdbm file at the same time. The procedure for opening a gdbm file is:
GDBM_FILE dbf;
dbf = gdbm_open ( name, block_size, read_write, mode, fatal_func )
Name is the name of the file (the complete name, gdbm does not append any characters to this name). Block_size is the size of a single transfer from disk to memory. This parameter is ignored unless the file is a new file. The minimum size is 512. If it is less than 512, dbm will use the stat block size for the file system. Read_write can have one of the following values:
GDBM_READER reader
GDBM_WRITER writer
GDBM_WRCREAT writer - if database does not exist create new one
GDBM_NEWDB writer - create new database regardless if one exists
For the last three (writers of the database) there is an extra value that that can be added to read_write by bitwise or, GDBM_FAST. This requests that gdbm write the database with no disk file syncronization. This allows faster writes, but may produce an inconsistant database in the event of abnormal termination of the writer.
Mode is the file mode (Read, Write or both) if the file is created. (*Fatal_func) () is a function for dbm to call if it detects a fatal error. The only parameter of this function is a string. If the value of 0 is provided, gdbm will use a default function.
The return value dbf is the pointer needed by all other routines to access that gdbm file. If the return is the NULL pointer, gdbm_open was not successful. The errors can be found in gdbm_errno for gdbm errors and in errno for system errors. (For error codes, refer to gdbmerrno.h)
In all of the following calls, the parameter dbf refers to the pointer returned from gdbm_open.
It is important that every file opened is also closed. This is needed to update the reader/writer count on the file. This is done by:
gdbm_close (dbf);
The database is used by 3 primary routines. The first stores data in the database.
ret = gdbm_store ( dbf, key, content, flag )
Dbf is the pointer returned by gdbm_open. Key is the key data. Content is the data to be associated with the key. Flag can have one of the following values:
GDBM_INSERT insert only, generate an error if key exists
GDBM_REPLACE replace contents if key exists.
If a reader calls gdbm_store, the return value will be -1. If called with GDBM_INSERT and key is in the database, the return value will be 1. Otherwise, the return value is 0.
If the data is stored for a key that is already in the data base, gdbm replaces the old data with the new data if called with GDBM_REPLACE. Two data items for the same key are not obtained and there is no error from gdbm_store.
To search for some data:
content = gdbm_fetch ( dbf, key )
Dbf is the pointer returned by gdbm_open. Key is the key data.
If the dptr element of the return value is NULL, no data was found. Otherwise the return value is a pointer to the found data. The storage space for the dptr element is allocated using malloc. Gdbm does not automatically free this data. It is the programmer's responsibility to free this storage when it is no longer needed.
To search for some data, without retrieving it:
ret = gdbm_exists ( dbf, key )
Dbf is the pointer returned by gdbm_open. Key is the key data to search for.
If the key is found within the database, the return value ret will be true. If nothing appropiate is found, ret will be false. This routine is useful for checking for the existance of a record, without performing the memory allocation done by gdbm_fetch.
To remove some data from the database:
ret = gdbm_delete ( dbf, key )
Dbf is the pointer returned by gdbm_open. Key is the key data.
The return value is -1 if the item is not present or the requester is a reader. The return value is 0 if there was a successful delete.
The next two routines allow for accessing all items in the database. This access is not key sequential, but it is guaranteed to visit every key in the database once. (The order has to do with the hash values.)
key = gdbm_firstkey ( dbf )
nextkey = gdbm_nextkey ( dbf, key )
Dbf is the pointer returned by gdbm_open. Key is the key data.
The return values are both of type datum. If the dptr element of the return value is NULL, there is no first key or next key. Again notice that dptr points to data allocated by malloc and gdbm will not free it for the developer.
These functions were intended to visit the database in read-only algorithms, for instance, to validate the database or similar operations.
File `visiting' is based on a `hash table'. gdbm_delete re-arranges the hash table to make sure that any collisions in the table do not leave some item `un-findable'. The original key order is NOT guaranteed to remain unchanged in ALL instances. It is possible that some key will not be visited if a loop like the following is executed:
key = gdbm_firstkey ( dbf );
while ( key.dptr ) {
nextkey = gdbm_nextkey ( dbf, key );
if ( some condition ) {
gdbm_delete ( dbf, key );
free ( key.dptr );
}
key = nextkey;
}
The following routine should be used very infrequently.
ret = gdbm_reorganize ( dbf )
If there are a lot of deletions and the developer would like to shrink the space used by the gdbm file, this routine will reorganize the database. Gdbm will not shorten the length of a gdbm file except by using this reorganization. (Deleted file space will be reused.)
If GDBM_FAST value is used in gdbm_open call, the following routine can be used to guarantee that the database is physically written to the disk file.
gdbm_sync ( dbf )
It will not return until the disk file state is syncronized with the in-memory state of the database.
To convert a gdbm error code into English text, use this routine:
ret = gdbm_strerror ( errno )
Where errno is of type gdbm_error, usually the global variable gdbm_errno. The appropiate phrase is returned.
gdbm now supports the ability to set certain options on an already open database.
ret = gdbm_setopt ( dbf, option, value, size )
Where dbf is the return value from a previous call to gdbm_open, and option specifies which option to set. The valid options are currently:
GDBM_CACHESIZE: Set the size of the internal bucketcache. This option may only be set once on each GDBM_FILE descriptor, and is set automatically to 100 upon the first access to the
database.
GDBM_FASTMODE:
Set fast mode to either on or off. This allows fast mode to be toggled on an already
open and active database. value (see below) should be set to either TRUE or FALSE.
value is the value to set option to, specified as an integer pointer. size is the size of the data pointed to by value. The return value will be -1 upon failure, or 0 upon success. The global variable gdbm_errno will be set upon failure.
For instance, to set a database to use a cache of 10, after opening it with gdbm_open, but prior to accessing it in any way, the following code could be used:
int value = 10;
ret = gdbm_setopt( dbf, GDBM_CACHESIZE, &value, sizeof(int));
The following two external variables may be useful:
gdbm_errno is the variable that contains more information about gdbm errors. (gdbm.h has the definitions of the error values and defines gdbm_errno as an external variable.)
gdbm_version is the string containing the version information
This gives an introduction to GNU Database manager. Embedded Shruti has used a version of GDBM ported into Windows CE so that it can be used by Pocket-PC Software Development Kit. Details of the GDBM functions used in Embedded Shruti will be provided in Chapter 4 which explains the complete design of Embedded Shruti.
Chapter 3
Share with your friends: |