Important: |
---|
This is retired content. This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This content may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist. |
Microsoft Corporation
June 2000
Summary:This article discusses Common Executable Format (CEF), a processor-neutral code format that enables the creation of portable applications across CPUs supported by Microsoft Windows CE. CEF enables Windows CE application developers to deliver products that support all the CPU architectures that run the Windows CE operating system. (17 printed pages)
Introduction
Common Executable Format (CEF) is a processor-neutral code
format that enables the creation of portable applications across
CPUs supported by Microsoft Windows CE. Microsoft eMbedded
Visual C++ can be configured to produce CEF code instead of a
native machine language code (such as MIPS or x86 code). In
eMbedded Visual C++, CEF Tools (compilers, linkers, and SDK) are
made available to the developer the same way a specific CPU target
(such as MIPS or ARM) is selected. When a developer compiles a CEF
application, the compiler and linker does everything but generate
machine-specific code. You still get a .dll or .exe, but the file
contains intermediate language instructions instead of native
machine code instructions. When the user installs a CEF application
on a Windows CE device, a translator generates the
corresponding native machine code for the device. CEF enables Windows CE application developers to deliver
products that support all the CPU architectures that run the
Windows CE operating system. Because CEF is an intermediate
language, processor vendors can easily add a new CPU family that
runs CEF applications. They just port Windows CE to their
process and write the CEF compiler. CEF for Microsoft eMbedded Visual C++ builds applications that
can be installed on any of the supported Windows CE processors
(currently ARM, MIPS, PPC, SHx, and x86) for that device category
(for example, Pocket PC). Because CEF is an intermediate CPU-independent language, a CEF
application can also be installed and run on any future
CEF-supported processor for that device category. All that would be
required is for the device operating system to include the CEF
translator whenever a new processor is supported. CEF-based applications run on a single platform (for example,
Pocket PC), but on different processors. For example, a CEF
executable file built for the Pocket PC will run on any Pocket PC
device. It will not run on a Handheld PC. CEF support is available
on the Pocket PC platform and any Windows CE platform created
with Microsoft Windows CE Platform Builder 3.0 where CEF
support has been enabled. Deploying applications to multiple CPUs imposes a cost to
developers who want to support a Windows CE platform. Although
standardized APIs and tools are generally available, it takes
resources to test, package, and distribute a product for multiple
CPUs. Multiple CPUs also impose costs on users. To install
applications, users also must know which CPU runs their
Windows CE devices. If a customer has a new device, the
available software may be limited. Users with devices supported by
different CPUs may also find that moving or sharing software is
complicated. CEF delivers a single executable file for multiple CPUs. This
feature can be useful whenever you must support multiple CPUs. For
example, you can post a single executable file for Pocket PC
devices on a Web site, which users can download for any Pocket PC
device using any processor. CEF is not appropriate when you want an
application optimized to run only on a particular processor. This
applies particularly if you are going to put an application in ROM
or otherwise design it for a particular processor. CEF provides processor compatibility for any application created
to run on a particular device (for example, the Pocket PC or the
Handheld PC, but not both). CEF does not provide for running an
application on different devices/platforms. Building a CEF application is simply a matter of choosing the
WCE CEF configuration for the build process. During compilation,
this configuration invokes the clcef.exe compiler to generate code.
When linking, it invokes the linkcef.exe linker. The final binary
is output in the same manner and named in the same manner as
processor-specific executables, but marked with a machine type of
CEF within the binary. When a user installs the common executable on a CEF-enabled
Windows CE device, the translator translates the common
executable file to the native executable file. Translators are
available for all Windows CE-supported processors. Two modes
of translation are available with CEF: device-side translation or
host (desktop)-side translation. The device-side translator
generates a native executable from a CEF executable with the
translator resident on the device ROM. The host-side or desktop
(PC) translator generates a native executable with a translator
resident on the desktop. The host-side translator is made available
with embedded Visual C++. The device translator is specific to a particular processor and
Windows CE device. The device version normally translates a
CEF executable to the native code of that processor when the user
installs the executable on the device. This occurs seamlessly,
without any indication to the user other than a brief pause for
translation. An operating system hook also catches any attempt to
load and execute a CEF .exe, .dll, or .ocx file automatically and
invokes the translator before running the file. The desktop translator is most useful during the development and
debugging of CEF applications. The desktop translator supports
debugging by translating .pdb information from CEF into native form
so that the result can be debugged. After translation occurs, the
native form of the application (with debug information) is
downloaded to the target device. Now the application can be
debugged remotely from the desktop with the debugger in eMbedded
Visual C++. Desktop translators for every processor family are included with
eMbedded Visual C++. These translators run on Microsoft Windows
2000, Microsoft Windows NT, or Windows 98 host computers
running the Microsoft eMbedded Visual Tools. One advantage of CEF is that you do not need to learn any new
language or language constructs to create a CEF application. You
can code in C++ and use the Windows CE APIs just as you would
for any specific processor. Although you must use C++, CEF does support C code with the /TP
/C /CEF build switches. The /TP switch is required to compile C
code as C++. However, if you do use C code, it must meet C++ rules
to provide valid input for a C++ compiler. Function definitions,
type conversions, and other language elements must follow C++
rules. If you want to use code that currently does not meet C++
requirements, you must upgrade it. All changes for C++ rules are
backward compatible; so, after you make changes, you can still
build your code with an ANSI C compiler.
These are the most common syntax changes required to meet C++
rules. Refer to a comprehensive book on the C++ language for a more
complete discussion of the differences between C and C++. The
changes themselves are syntactic and result from the stricter
compiler philosophy of C++. Changing your code to conform to the
stricter rules will not change your algorithms nor prevent you from
compiling your source code as ANSI C for other projects. To build a CEF executable file for an application, you must
configure the Project for WCE CEF instead of a native processor.
Use
Set Active Configurationon the
Buildmenu to select the active project configuration. You
can also select the active configuration on the
WCE Configurationtoolbar. Then, when you build your project,
eMbedded Visual C++ compiles the source code as CEF-based .exe,
.dll, or .ocx file. Choose
Settingson the
Projectmenu to configure project settings for a CEF project.
Choose the
C/C++tab of the
Project Settingsdialog box to check the settings for each
category listed in the
Categorybox.
Figure 1. Project Settings dialog box
The following table lists the appropriate
C/C++tab settings for a CEF project. In the eMbedded Visual C++ IDE, building a CEF application is no
different from building an application for any specific CPU.
Compilation is performed by Clcef.exe and linking by Linkcef.exe.
The CEF compiler and linker do support a few special options. To
see all the options available for either Clcef.exe or Linkcef.exe,
type clcef /? or linkcef /? at the command prompt. The following switches are specific to the CEF compiler: The
noWchar_tand the
/noResultand
/noBoolswitches may cause problems for linking to standard
Windows CE import libraries. If the types disabled by these
switches are used in function signatures, the linker will fail to
match the functions when the types are disabled. The
/MACHINE:CEFswitch is required for linking CEF files. The
CEF argument is the only one supported for the
/MACHINEswitch for Linkcef.exe. The CEF argument is not
supported by Link.exe, which does not link CEF binaries. The
/SUBSYSTEMswitch tells the operating system how to run an
.exe file generated by a build. For a CEF build, specify
/SUBSYSTEM:WINDOWSCE. The
/SUBSYSTEM:WINDOWSCEoption is required for Linkcef.exe. This
is also the only subsystem you can specify for Linkcef.exe. Use
/WINDOWSCE:CONVERTfor linking CEF builds. The
EMULATIONargument is used for building a desktop Windows CE
application that runs under the emulator, and Linkcef.exe does not
link binaries for emulation. When you build a debug version of a CEF application, all
debugging takes place on a native translation of the application.
The linker builds a CEF PE (such as .exe, .dll, or .ocx) file and a
.pdb file. The desktop translator converts the CEF PE and .pdb
files to a native format. This enables the source code and the
native executable to stay synchronized, so that the native version
of the .pdb correctly references source line numbers while you
debug the native version. The primary objective of CEF is to provide developers with a
simple way to distribute their product for multiple CPUs with
Windows CE. For most of your debugging, use the native executable
for the CPU on your Windows CE device. The CEF code is optimized,
and optimized code can be difficult to debug. You also lose a lot
of information in the compilation of source code to CEF and in the
translation to native code. Develop the product on an available
CPU. Test the CEF build only after the code has been debugged in
the native format for the CPU, and the project is near completion.
CEF is for delivering a product, not for developing a product. We also recommend against transferring the debug version of a
CEF build, particularly a debug static MFC build, to a device. A
debug build requires several times more translation resources than
a regular build. Transferring a debug version to the host may work
if the device CPU has a lot of memory, but the design is not made
for doing this. For testing purposes, you can choose whether to automatically
download an application to the attached device after building it.
You can change the download options on the
Downloadtab of the
Optionsdialog box (choose
Optionson the
Toolsmenu).
Figure 2. Options dialog box
Select or clear the check boxes to always download the binary or
dependencies to the target device after you compile the
project. If you clear the
Always download ...checkboxes on the
Downloadtab of the
Optionsdialog box, you can download the application manually
after you compile it by choosing
Update Remote Output Fileon the
Tools/Buildmenu.
Figure 3. Choosing Update Remote Output File(s)
You can also choose whether to translate the CEF executable to
native format before downloading by selecting
Always translate CEF executable to native format before
downloadingon the
Downloadtab of the
Optionsdialog box. If you clear this option, the executable
will be translated to native format when it is executed on the
target device.
Figure 4. Options dialog box
If a CEF application is going to be installed on more than one
computer (for example, passed around on a flash card), you should
always use a CAB file to install the application. When the
translator installs from an .exe, .dll, or .ocx file, it replaces
the original file with the translated file. In contrast, when you
use a CAB file, the Windows CE loader (Wceload.exe) first unpacks
the CAB and stores the executable files. The loader then calls a
Setup.dll unpacked from the CAB, and it in turn calls the CEF
translator. The CEF files are still overwritten by the native
executable files, but the CAB files are retained and can be used
elsewhere. If a CEF application is to be installed only once (for example,
an .ocx file or isolated binary downloaded and installed from a Web
page), you may choose to use a bare .exe, .dll, or .ocx file.
Because no CAB is involved, the file will simply be translated and
overwritten the first time it is run. In order to use it on another
device, the user will have to get a new copy from the Web page or
other source. If you are using Platform Builder to define your own platform,
you should configure Wceload.exe as part of your platform to
provide CEF support. The CEF translator can be invoked by running an executable
(Ceft.exe) or by having the operating system automatically detect
the CEF application when the application is first executed. On a custom-built platform configured with the Platform Builder
product, Ceft.exe is available only when it is included in the
platform configuration. When you are working in eMbedded Visual C++, the IDE is
initially configured to automatically translate the CEF file to the
native executable file before it downloads the executable file to
the native device. To turn this option on or off for testing and
debugging, choose
Optionson the
Toolsmenu to display the
Optionsdialog box. Then, on the
Downloadtab, select or clear the
Always translate CEF executable to native format before
downloadingcheck box.
Figure 5. Options dialog box
If you clear this check box but leave the other two
Download Optionscheck boxes selected, the IDE downloads the
CEF file to the target device without translating it to the native
executable. The CEF file will then be translated on the target
device the first time that you run it. If the CEF executable file has not been translated when you
begin a debugging session, the IDE prompts you to convert the file
before beginning the session. Furthermore, during a debugging
session, the debugger requires translation of any program not
translated during the download, even if you manually translate it
in the output directory or on the device. This is because the
debugger requires translation of the debug information, and only
the translator on the host computer supports translation of the
debug information. On the desktop computer and on Windows CE devices that support
the CEFT utility, you can use Ceft.exe to manually translate CEF
executables. Ceft.exe on the desktop is stored in the Microsoft
Embedded Tools\EVC\
osfolder
CEFT
-cpu cefexecutable [[path]nativeexecutable]
CEFT
cefexecutable [[path]nativeexecutable]
The
cpuis one of the CEF-supported operating systems. Currently,
you can use ARM, MIPS, SH3, SH4, PPC, or x86. These can change as
Microsoft supports additional Windows CE operating systems. The
help displayed by typing CEFT /? lists the operating systems
supported by the Ceft.exe. This argument is unavailable on a
Windows CE device, where CEFT automatically calls the
device-specific translator stored in ROM. The
cefexecutableis a CEF executable file that was compiled in
the IDE or by Clcef.exe on the command prompt. The
nativeexecutablespecifies the output file, which is an
executable for the designated operating system. If you do not
specify an output file, then CEFT generates a name using
cpu.cefexecutable. If you are testing a CEF application on an ODO, device-side
translation of the CEF executable cannot take place when attempting
to execute a CEF application in the release directory (specified by
the _FLATRELEASEDIR environmental variable). Kernel-mode hooks for
CEF applications do not affect applications run in the
_FLATRELEASEDIR directory. In order to perform device side
translation on an ODO, the executable must be transferred to the
device itself. ODO refers to the Hitachi D9000 Handheld PC hardware development
platform. This device supports microprocessors from multiple
vendors. MkCEFlib prepares import libraries for CEF applications, which
allow native code DLLs to be called by CEF applications or CEF
DLLs. CEF uses a different binary format for its libraries to which
native-code libraries must be converted to be used by a CEF
application. MkCEFlib extracts the contents of native import
libraries and compiles an equivalent CEF import library. You link
this library to your CEF project to enable the compiled CEF
application to use the native DLL. The CEF translator handles APIs exported by name. Although C++
decorated names vary slightly on different CPU architectures, the
translator transforms the CEF form of the name to the appropriate
decorated name for a particular CPU. The native-code DLL must provide a uniform API that exports the
same functions on all supported CPUs. If a native-code DLL exports
CPU-specific functions, a CEF application should never call them.
We strongly recommend that you exclude any CPU-specific functions
from the CEF import library. If your native-code DLL exports any functions by ordinal, you
must be careful to use identical ordinals on all CPUs. There are
different ways to set up ordinals, but you must be sure that they
are the same on every CPU supported by your DLL. If a DLL is not
standardized across CPUs, then CEF application cannot use it
transparently on every CPU. Be sure that the native-code DLL is stable before you run
MkCEFlib. MkCEFlib must do a compilation for every API function,
which may require something on the order of 10 minutes for every
100 functions. Any time you change the export set of functions for
a DLL, you must rerun MkCEFlib. If you are still developing,
testing, or debugging a DLL, running MkCEFlib consumes time very
likely better spent on those tasks. When you are ready to create
the CEF import library for the DLL, complete the following steps
before you run MkCEFlib.
An inclusion source file is a C++ source file that includes all
the header files necessary for using the APIs of the target DLL.
Prepare this exactly like a normal C++ source file with all the
required headers but no source code. If the DLL exports in C style
rather than C++, remember to use extern "C" to prevent the compiler
from decorating the C function names:
If there are any exports that are not defined in standard header
files and you need to make them accessible to the CEF application,
then add the proper definitions to your inclusion source file.
There may be exported functions, such as CPU-specific function,
in the headers specified by the inclusion source file that should
not be accessible to a CEF application. Often specified header
files may already surround these with CPU-specific #ifdef
statements, thereby avoiding any problem.
If an API has not been defined for CPU-specific compilation,
then the easiest way to make it inaccessible to the CEF application
is to #define the exported function name to some other name in the
inclusion source file prior to including the corresponding header
file. MkCEFlib discards any name that it cannot match to an export
in the native .lib file. MkCEFlib also discards any export that it
cannot match to a declaration in the inclusion source file.
MkCEFlib generates a log that you can use to identify included and
discarded functions.
After you complete these steps, you can run MkCEFlib as
follows. After you complete the required preparations, follow these steps
to create a CEF import library.
When you run MkCEFlib, it performs actions in the following
order:
You can see a list of the exports in the workDirPath\libName.log
text file. If the export had a problem, it is marked in square
brackets; for example, "[MISSING OBJ]". You should examine this log
file after running MkCEFlib. The following can cause problems:
MkCEFlib creates a .cefdef import library file for a CEF
application. The location of Mkceflib.exe is in Microsoft eMbedded
Tools\EVC\
WCEversion
To run MkCEFlib, use the following command line syntax.
MkCEFlib.exe returns 0 if there is no error or 1 if it was
unsuccessful. CEF enables Windows CE application developers to deliver
products that support all the CPU architectures that run the
Windows CE operating system. Because CEF is an intermediate
language, processor vendors can easily add a new CPU family that
runs CEF applications. They just port Windows CE to their process
and write the CEF compiler.
CEF for Microsoft eMbedded Visual C++
Advantages and Disadvantages of CEF
How CEF Works
The Device Translator
The Desktop Translator
CEF Language Requirements
Configuring a CEF Project
Limitations and Recommendations
Building and Linking a CEF Application
Debugging a CEF Application
Delivering a CEF Application
Distributing CEF Applications as Bare
.exe, .dll, or .ocx File
CEF Translator Reference
MkCEFlib Reference
Requirements for the Native-Code
DLL
Preparing to Run MkCEFlib
Running MkCEFlib
Actions Performed by MkCEFlib
Troubleshooting MkCEFlib
MkCEFlib Command Line
Conclusion
Introduction
CEF for Microsoft eMbedded Visual C++
Advantages and Disadvantages of
CEF
Advantages of CEF
Disadvantages of CEF
How CEF Works
The Device Translator
The Desktop Translator
CEF Language Requirements
Configuring a CEF Project
Project Settings for a CEF Build
Category
Setting
Notes
General
Optimization
CEF optimization is less drastic than for other
build configurations. This means that there will be less difference
between size and speed in optimized code compared with
non-optimized code.
Common Options
/CEF switch required/TP switch required for C
code.
C++ Language
Representation method
Best-Case Always* (only available option).
Code Generation
Processor
DEFAULT (only available option).
Use run-time library
CE Run time* (only available option).
Struct member alignment
8 Bytes* (required).
Customize
No special settings.
Listing Files
No special settings.
Optimizations
Optimizations for CEF builds do not have nearly the
effect as when building for a native compiler.
Precompiled Headers
No precompiled headers available.
Preprocessor
No special preprocessor settings.
Limitations and Recommendations
Group 1
Group 2
wWinMainCRTStartup
Main
WinMainCRTStartup
Wmain
mainCRTStartup
WinMain
_DllMainCRTStartup
WWinMain
DllMain
Building and Linking a CEF
Application
Overview
CEF Compiler Options
Switch
Description
/cef
Compile for Windows CE CEF (required)
/noHRESULT
Disable intrinsic HRESULT type
/noWchar_t
Disable
wchar_tkeyword
/noBool
Disable
boolkeyword
/MP
Compile using multiple processes
CEF Linker Options
Debugging a CEF Application
Overview
Strategy
Methodology
Automatic Binary Download
Manual Binary Download
Host/Device-Side Translation
Delivering a CEF Application
Using a CAB File to Distribute CEF
Applications
Distributing CEF Applications as
Bare .exe, .dll, or .ocx File
CEF Translator Reference
Configuring CEF Translation During Host
Download
Translating a CEF Application While Debugging
CEFT Command Line
\
Bin folder (where
osfolderis WCE300 or later). Use the following command line
syntax for the CEFT utility.Desktop Syntax
Windows CE Device Syntax
Performing Device-Side Translation on an ODO
MkCEFlib Reference
Requirements for the Native-Code
DLL
Preparing to Run MkCEFlib
A MIPS version of a DLL is ideal. Do not use an x86 version as
the base .lib, because its C++ decoration scheme cannot be reversed
into a standard form. Any of the RISC CPUs has simpler decoration
schemes and is suitable to use as the base .lib.
extern "C" { #include "MyCHeader.h" }
Running MkCEFlib
Prefix any unspecified paths to the INCLUDE environment
variable with the set command (for example, set
c:\headers;%include% to prefix "c:\headers" directory to the
INCLUDE value).
Actions Performed by MkCEFlib
Troubleshooting MkCEFlib
MkCEFlib Command Line
\
BIN. Mkceflib.exe is included with version 3.0 or
later of the Windows CE operating system. The default location is
specified in the PATH variable created by the Wcecef.bat batch
file, also located in Microsoft eMbedded Tools\EVC\
WCEversion
\
BIN.
MkCEFlib
libname inclusionfile workingfolder
The
libnamefield is the fully qualified name of a native import
.lib file. This corresponds to a CPU version of the
DLL.
The
inclusionfilefield is the fully qualified name of the
inclusion source file for the project.
The
workingfolderis the working directory where MkCEFlib saves
all intermediate and result files.
Conclusion