[S60] unique ARM platform issue writable static data in DLLs

Source: Internet
Author: User

 

[S60] unique ARM platform issue writable static data in DLLs

Original article address:

Http://www.cppblog.com/gtwdaizi/articles/51908.html

 

[S60] proprietary ARM platform issues writable static data in DLLs2007-07-08
When compiling the ARM platform program, the following error message is displayed:
Error: DLL 'appname [uid]. app' has initialised data.
Or:
Error: DLL 'appname [uid]. app' has uninitialised data.
(The application with the extension app is actually a DLL .)

This problem does not occur when compiling the simulator. This once led me to complete the design, encoding, and debugging,
Forced to abandon the original design.

The literal meaning of this error message cannot be seen.Initialised andUninitialised has the same problem.
The real meaning is that the dll contains writable global variables.

We know that when the program is running, the DLL will only be loaded once. On Windows, each process has its own DLL space. That is to say, different processes load the same DLL and are independent of each other. It is shared only within one process. However, the s60 platform is designed to allow all processes to share the same DLL space. This design is obviously out of memory savings and is necessary. However, this poses a problem, that is, the DLL cannot contain writable global variables, otherwise it will cause confusion. Modifying the variables of process a directly affects process B, which is not expected by the program designer. Therefore, the compiler of the s60 platform prohibits the declaration of writable global variables in the DLL. However, global variables can still be used, as long as the const statement is added.

Generally, you are not encouraged to use writable global variables when designing DLL. Even on Windows, the writable global variables of DLL may cause problems between different modules. When this compiler error occurs, try to modify the design and avoid using global variables.

However, because the app is actually a DLL, even the s60 main program cannot use writable global variables, which sometimes becomes a problem, global variables are an important means of implementation. In this regard, s60 provides local thread storage (Thread Local Storage) To solve the problem.
Two functions are critical to TLS:
Void dll: settls (void *) andVoid * dll: TLS ()
Settls is used to save any type of pointer to the local storage of the thread, and TLS () extracts the pointer.
The Pointer Points to a memory allocated on the heap. A thread can have only one local storage variable. Therefore, if you have many global variables, You need to define a structure and encapsulate all global variables in it. This is quite awkward, but s60 3rd is said to support DLL writable global variables.

TLS sample code:

Set
Globaldata * P = new globaldata ();
If (P)
{
DLL: settls (P );
}

Use
Globaldata * P = (globaldata *) dll: TLS ();

 

How to define global variables on Symbian

Method 1 (recommended) defines this variable as a private member of the Appui class. When creating a view, this variable is passed as a reference (or pointer) to the view, in this way, the view can be accessed at any time.

Method 2: define this variable as a private member of the Appui class and write public access functions for it.
// Cmyappui
Public: // New Methods
Tint share (); // return ishare
PRIVATE:
Java mobile network [www.cnjm.net] tint ishare;
Access this variable in view in the following way:
// If the view inherits from the caknview
Cmyappui * Appui = static_cast <cmyappui *> (Appui ());
Appui-> share ();//
// If the view is of another type
Cmyappui * Appui = static_cast <cmyappui *> (ccoeenv: static ()-> Appui ());
Appui-> share ();//
Method 3: Use the single-State class. Refer to the documentation on the Nokia Forum:
Tip of the month: how to implement a singleton class in Symbian OS

 

How to implement a singleton class in Symbian OS ID: tts000222

Version 1.1:
Published at www.forum.nokia.com on October 19,200 6.

Overview

The Singleton pattern is one of the best-known patterns in software engineering. essential, a singleton is a class which only allows a single instance of itself to be created, and usually gives simple access to that instance.

How to Use Thread Local Storage (TLS) to implement a singleton class

In Symbian OS, each DLL that is loaded in each thread has a machine word of thread-specific memory that can be written to and read-but no other static memory, which is why you can't have static class member variables. since static class member variables are usually used to implement the Singleton pattern, in Symbian OS we have to get around this, for instance by using TLS.

The following code demonstrates a singleton object whose newl function uses TLS to test whether an object of its own type has been created. if it has, it simply returns the pointer stored in TLS, converted to its own type. if not, it instantiates an object of its own type, stores it in TLS, and then returns it.

Note that this assumes that no other class in the DLL that includes des this class uses TLS. if this is not the case, you must write a singleton manager class, which uses TLS to store a pointer to a structure of pointers to all the singleton classes that the program needs.

Example 1: Singleton implementation based on TLS

====================

Cmysingleton. h

====================

 

Class cmysingleton: Public cbase

{

Public: // constructor and destructor

Static cmysingleton * newl ();

Virtual ~ Cmysingleton ();

PRIVATE: // Constructors

Cmysingleton (); // Private because of the Singleton pattern; it is

// Guaranteed that only newl will call it

Void constructl ();

Public: // other functions

...

PRIVATE: // other functions

...

PRIVATE: // data

...

}

 

======================

Cmysingleton. cpp

======================

 

Cmysingleton: cmysingleton * newl ()

{

Cmysingleton * Singleton;

// Check Thread Local Storage:

If (DLL: TLS () = NULL)

{

// TLS is still null, which means that no cmysingleton has

// Been instantiated yet. do so now, and return that

// Instance:

Singleton = new (eleave) cmysingleton ();

Cleanupstack: pushl (Singleton );

Singleton-> constructl ();

Cleanupstack: Pop (Singleton );

// Store a pointer to the new instance in Thread Local Storage:

Tint err = dll: settls (static_cast <Tany *> (Singleton ));

If (ERR = kerrnone)

{

Return Singleton;

}

Else

{

Delete instance;

User: Leave (ERR );

Return NULL;

}

}

Else

{

// Cmysingleton has been instantiated once already, so return

// That instance:

Singleton = static_cast <cmysingleton *> (DLL: TLS ());

Return Singleton;

}

}

 

TLS on s60 3rd edition

Since applications from s60 3rd edition onwards are implemented as EXE programs, dll: TLS () is not available anymore. Instead, TLS functionality is implemented in usersvr class (e32svr. h ):

Static tint dllsettls (tint ahandle, Tany * aptr );

Static Tany * dlltls (tint ahandle );

Static void dllfreetls (tint ahandle );

Note that EXE programs can contain writeable static data, but this is not recommended to be used failed T as a last resort.

Using class ccoestatic to implement a singleton class

A simpler way of implementing singletons than using TLS is possible for those classes which use the ccoeenv class. Since ccoeenv is a part of the UI control framework, this concerns only applications, not application engines.

This applies also to s60 3rd edition and later editions.

Example 2: Singleton implementation based on ccoestatic

====================

Cmysingleton. h

====================

 

/**

* Example implementation of a singleton class by means of inheriting

* From ccoestatic.

*/

Class cmysingleton: Public ccoestatic

{

 

Public: // constructors and destructor

 

/**

* Returns an instance of this class. When called for the first

* Time, a new instance is created and returned. After that,

* Calling instancel returns the same instance that was created

* Earlier.

*

* @ Return a pointer to a cmysingleton object

*/

Static cmysingleton * instancel ();

 

PRIVATE: // Constructor

 

/**

* Default constructor is private because we are using

* Singleton design pattern.

*/

Cmysingleton ();

 

...

 

}

 

 

======================

Cmysingleton. cpp

======================

 

//-------------------------------------------------------------------------

// Cmysingleton: cmysingleton

// C ++ default constructor. It is private because we are using

// Singleton design pattern.

//-------------------------------------------------------------------------

Cmysingleton: cmysingleton ()

: Ccoestatic (kuidmysingleton)

{

}

 

//-------------------------------------------------------------------------

// Cmysingleton: instancel

// Returns an instance of this class. When called for the first time,

// A new instance is created and returned. After that, calling

// Instancel returns the same instance that was created earlier.

// Note that the UID passed to ccoeenv: static needs to be unique.

//-------------------------------------------------------------------------

Cmysingleton * cmysingleton: instancel ()

{

Cmysingleton * instance = static_cast <cmysingleton *>

(Ccoeenv: static (kuidmysingleton ));

If (! Instance)

{

Instance = new (eleave) cmysingleton;

Cleanupstack: pushl (instance );

Instance-> constructl ();

Cleanupstack: Pop ();

}

Return instance;

}

 

========================================================== ==============================

========================================================== ==============================

I add:

DLL files compiled by the Symbian system cannot use writable static variables. They are for "v8.1a" and earlier versions of "Symbian OS", and later versions (such as "V9 ") this restriction does not apply (epocallowdlldata can be used), but is not recommended.

 

In C language engineering, it is best not to have writable Global static variables (Global writeable static data). In some mobile phone versions, global variables are not supported, but global static constants may exist, note This statement for global pointer constants. For example, static const char * const requires two "const ". If a Global static variable or a static constant occurs, add the "epocallowdlldata" identifier to the MMP file. Otherwise, a compilation error occurs. For writable Global static variables, you can put all global variables in a struct structure, and then use dll: settls () and DLL: TLS () as the pointer to this structure () the problem is that C ++ cannot be called in C-compiled code. The most stupid solution is to store the pointer value in a file;

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.