RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


BREW Up a Better Way to Synch Data Between Apps Using a Singleton : Page 3

The most elegant way to ensure the synchronization of data between two separate apps is to use a singleton. The problem is that BREW doesn't support global or class member variables. Learn how BREW's IModule interface lets you implement singletons—without relying on the usual methods.

The IModule Subclass Representation
The code below creates the data structure that represents the IModule subclass instance. But first, take a look at the in-core representation of the singleton’s IModule subclass:

typedef struct _SSingletonModule                                     
   uint32           nRefs;			
   IShell           *pIShell;		


   /// Our singleton pointer.
   SSingletonData   *pInstance;
} SSingletonModule;
This is pretty basic stuff if you've built extensions before. The first line declares the virtual function table for this class, which implements IModule. The next lines are the typical baggage carried by all classes—a reference count and a pointer to the system shell. Next are two function pointers required for static extensions (those extensions compiled in-line with the ROM), but unused for OTA applications.

Author's Note: I choose to keep these (and code you see in later listings) for static extensions in all of my code, because I've been fortunate enough to work in settings where I've needed to quickly port existing code to work in ROM for handset manufacturers.

Finally comes the secret sauce: the last line will contain a pointer to the singleton class when it's created.

The IModule Entry Point
Next, you need to write the entry point for the module. This isn't hard, both because there's a reference implementation in AEEModGen.c and because with one notable exception, it's the same as the first-stage constructor for other classes (Listing 1).

This code has two interesting chunks: the plethora of preprocessor directives in declaring the entry point (the first eighteen lines) and the simulator-specific bits in AEEStaticMod_New. These are necessary because the manner in which the module is loaded depends on the platform:

  • In the emulator, AEEMod_Load is exported from the module's DLL.
  • In some production environments internal to QUALCOMM, the entry point is actually called module_main.
  • In all other cases, for OTA configuration, the entry point is AEEMod_Load, and it’s declared the entry point during the link process.
Regardless, AEEMod_Load is really just a wrapper function for AEEStaticMod_New, which is the function static builds invoke when creating static modules. This function is much like the AEEClsCreateInstance for any class, with two key differences: it must accept pointers to creation and destruction functions when invoked during static builds, and; it must tuck away the shared pointer to the BREW helper utilities on the emulator. This work occurs in the eight lines wrapped by an AEE_SIMULATOR preprocessor check in AEEStaticModNew, and tucks away the pointer to the helper function virtual table in the global variable used by the module. If you're really curious about how this works, take a close look at AEEStdLib.h in any version of the QUALCOMM BREW SDK.

Close Icon
Thanks for your registration, follow us on our social networks to keep up-to-date