|
||
app
s to
exe
s
This document provides step-by-step instructions on how to convert an existing DLL-type application to a new style EXE-type application. The conversion of embeddable applications requires more work than non-embeddable, so the two types are described separately.
The TARGETTYPE
in the MMP file changes from
app
to exe
. However, for applications that need to
also run on the EKA1 emulator, the TARGETTYPE
must be
exedll
. Hence, the following lines should replace the existing
TARGET
and TARGETTYPE
lines:
#if !defined(EKA2) && defined(WINS)
TARGET ExeAppTest.app
TARGETTYPE exedll
deffile \epoc32\release\wins\exedllapp.def
#else
TARGET ExeAppTest.exe
TARGETTYPE exe
#endif
The TARGET
filename's extension should be
.exe
. It is also important is that the second UID (the application
identifier) remains the same: 0x100039CE
. For EKA1 emulator
builds, the binary produced is a DLL with the entry point exported at ordinal
one. Therefore, as in the example above, a deffile
statement is
used to define the export.
The stack size should be explicitly set to a value greater than the
default of 8K. Previously, applications were launched in a process initiated by
apprun.exe
which had a stack size of 20K. Therefore, to ensure the
converted application will not have any problems with stack size, this is the
minimum value the stack size should be set to. This is done in the MMP file
with the line:
epocstacksize 0x5000
Note that embedding an EXE-app inside another EXE-app (see the Embeddable applications section below) is enough to overflow the default 8K stack.
The API for starting the application framework is in
eikcore.dll
, so eikcore.lib
needs to be listed in the
LIBRARY
section of the MMP file.
The EikStart::RunApplication()
function needs to
be called from the EXE's entry point, passing as an argument a
pointer-to-function which creates an instance of the
CApaApplication
-derived class (this is the same function
that is exported at ordinal 1 for DLL-apps). In EKA1 emulator builds, the
command line also needs to be passed to this function. This is demonstrated by
the following code, which works for all builds:
#include <eikstart.h>
LOCAL_C CApaApplication* NewApplication()
{
return new CExampleApplication;
}
GLDEF_C TInt E32Main()
{
return EikStart::RunApplication(NewApplication);
}
#if defined(__WINS__) && !defined(EKA2)
GLDEF_C TInt E32Dll(TDllReason)
{
return KErrNone;
}
EXPORT_C TInt WinsMain(TDesC* aCmdLine)
{
return EikStart::RunApplication(NewApplication, aCmdLine);
}
#endif
If the application needs to store configuration or application data, a
private directory will need to be created. For more information on private
directories, see the documentation on the RFs
class.
The relevant functions in the RFs
class for
private directories are are:
RFs::PrivatePath
gets the private path for a process
RFs::CreatePrivatePath
creates the private directory for a process on the specified drive
RFs::SetSessionToPrivate
sets the session path to point to the private directory on the specified drive
Embeddable applications are implemented as ECom plug-ins. The
CApaApplication
class defines the interface, and the
majority of an application's code will be in the ECom plug-in. To allow an
embeddable application to run as a standalone application a small EXE also
needs to be created which calls the
EikStart::RunApplication()
function, but this time
specifying the UID of the ECom plug-in rather than a pointer to the factory
function.
This section describes the steps for converting an existing embeddable application to an ECom plug-in and executable.
The MMP file of the embeddable application needs to be changed to create an ECom plug-in instead of a DLL application, using the following lines:
TARGET Example_embedded.dll
TARGETTYPE PLUGIN
UID 0x10009d8d 0x01010101
where 0x01010101
is a newly allocated UID, not the
application's original UID - this is used elsewhere, see below.
The MMP file also needs to create the ECom plug-in resource, and the original resource line needs to be modified so the application resource file(s) are created in the correct directory.
START RESOURCE 01010101.rss
#ifdef SYMBIAN_SECURE_ECOM
TARGET Example_embedded.rsc
#endif
END
START RESOURCE Example.rss
HEADER
TARGETPATH \resource\apps
LANG SC
END
The 01010101.rss
ECom plug-in resource file uses the
standard format for ECom plug-ins, where the interface definition UID for
CApaApplication
s is:
const TUid KUidFileEmbeddedApplicationInterfaceUid={0x101f8c96};
The implementation UID should be the application's original UID
(0x01234567
in the example below), and therefore the file should
look like this:
#include <RegistryInfo.rh>
RESOURCE REGISTRY_INFO
{
dll_uid = 0x01010101;
interfaces =
{
INTERFACE_INFO
{
interface_uid=0x101f8c96;
implementations=
{
IMPLEMENTATION_INFO
{
implementation_uid=0x01234567;
version_no=1;
}
};
}
};
}
ECom.lib
should be included in the library section in
the MMP file.
The AIF section is not needed as the application information is now
provided by the registration file, localisable resource file and icon file. A
registration file should be provided to inform the framework about the
embeddable capability of the plug-in. This can be achieved by setting the
‘embeddability' flag in APP_REGISTRATION_INFO
structure. If
a stub EXE is provided to start the ECom plug-in, set the embeddability flag to
KAppEmbeddable
, otherwise set
KAppEmbeddableOnly
. For more information about the
registration file please refer to the
How to port guide - data caged applications document.
The code for the application should no longer export the
NewApplication()
function at ordinal 1, but instead the function
which informs the ECom framework of the implementations this ECom plug-in
provides (as is standard for an ECom plug-in). This is demonstrated by the
following code:
#include "ExampleApp.h"
#include <ecom.h>
#include <implementationproxy.h>
GLDEF_C TInt E32Dll(TDllReason)
{
return KErrNone;
}
LOCAL_C CApaApplication* NewApplication()
{
return new CExampleApplication;
}
LOCAL_D const TImplementationProxy ImplementationTable[]=
{
IMPLEMENTATION_PROXY_ENTRY(0x01234567, NewApplication)
};
EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
{
aTableCount=sizeof(ImplementationTable)/sizeof(ImplementationTable[0]);
return ImplementationTable;
}
The MMP file for the standalone EXE should create an EXE-app (as
described in the
Embeddable applications section above) and the EXE should have the application's
UID as its third UID. The AIF file should be replaced by a registration file.
The registration file is used to inform the framework that the application is
capable of being embedded by setting KAppEmbeddable
in the
‘embeddability' field of the APP_REGISTRATION_INFO
structure.
#if !defined(EKA2) && defined(WINS)
TARGET Example.app
TARGETTYPE exedll
deffile \epoc32\release\wins\exedllapp.def
#else
TARGET Example.exe
TARGETTYPE exe
#endif
UID 0x100039CE 0x01234567
TARGETPATH \sys\bin
EPOCSTACKSIZE 0x5000
SOURCEPATH .
SOURCE Example_Standalone.cpp
USERINCLUDE .
SYSTEMINCLUDE \epoc32\include
// Application exe registration resource file
start resource Example_reg.rss
targetpath \private\10003a3f\apps
lang sc
end
LIBRARY euser.lib apparc.lib eikcore.lib
The executable need only be a 'stub' to start the application architecture with the ECom UID. Therefore the single source file should contain code similar to the following:
#include <e32std.h>
#include <eikstart.h>
const TUid KExampleUid = {0x01234567};
GLDEF_C TInt E32Main()
{
return EikStart::RunApplication(KExampleUid);
}
#if defined(__WINS__) && !defined(EKA2)
GLDEF_C TInt E32Dll(TDllReason)
{
return KErrNone;
}
EXPORT_C TInt WinsMain(TDesC* aCmdLine)
{
return EikStart::RunApplication(KExampleUid, aCmdLine);
}
#endif
Finally, the bld.inf
for the application needs to be
modified to build both MMP files, for example:
PRJ_MMPFILES
Example_embedded.MMP
Example_standalone.MMP
To add a new document to an application, an overload of
CApaProcess::AddNewDocumentL()
has been created which can
accept an ECom UID or an ECom CImplementationInformation
reference. However, the existing overload of AddNewDocumentL()
handles the case where the application for the document is an EXE, and attempts
to find an ECom plug-in with the correct UID to create the embedded
application. Therefore, existing applications (which perhaps offer a list of
available embeddable applications to the user) do not need to be modified.
Also, the internalising and externalising of embedded documents (via
CApaDoor
, etc.) works with no modifications necessary.