Everybody who has tried to make DAs (Desk Accessories) knows you can’t use global variables in the code. There are ways to go around that problem, of course, but all I have seen are either slow, like reading and writing to databases, or complicated to use, like using Feature Memory (I never figured out how to read from it!). The easiest way I found is to use Application-Defined Features to store pointers to variables in Dynamic Heap. It practically gives you real global variables to use in your DA! This is how it works:

1. Define your application creator
#define DACREATOR 'myDA'

2. Define a the name of your feature ID giving it a unique number. To make it real easy, give it a name reminding of the global which pointer it will contain. I put an “f” in front of it.
#define fBuffer 1

3. For ease of use, put in the following two functions already published on TamsPalm:
//------------------------------------
MemPtr malloc(UInt16 size) {
MemHandle h = MemHandleNew(size);
if (!h) {
return NULL;
}
return (MemPtr) MemHandleLock(h);
}

//------------------------------------
void free(MemPtr ptr) {
MemHandle h = MemPtrRecoverHandle(ptr);
if(!h) return;
MemHandleUnlock(h);
MemHandleFree(h);
ptr = NULL;
}

4. Put in two functions that will make it easy to set and get the App Defined Feature which will contain the pointers to the globals.
// ------------------------------------
UInt32 GetFtr(UInt16 ftrID){
UInt32 test=0;
Err e=FtrGet(DACREATOR, ftrID, &test);
if (e!=0){
FtrSet(DACREATOR, ftrID, 0);
test=0;
}
return test;
}

// ------------------------------------
void SetFtr(UInt16 ftrID, UInt32 val){
FtrSet(DACREATOR, ftrID, val);
}

5. Declare your global variable and place them in the Dynamic Heap. To use the Dynamic Heap is really cool. You can almost put as much as you like up there without affecting the stack which has a limited space already used by the app running when the DA is launched.
char *Buffer=malloc(32000);

6. Set the pointer as a feature value.
SetFtr(fBuffer, (UInt32)Buffer);

7. To access the global variable in your functions, you need to get the pointer to it. That is done like this:
char *Buffer=GetFtr(fBuffer);
StrCopy(Buffer,"Hello!");

or even use it directly as in this example:
StrCopy((char *)GetFtr(fBuffer),"Hello!");

8. When quitting the DA, you need to free the global variable. Don’t forget it! It’s more important for a DA than for normal app. Quitting a normal app releases the variables but quitting a DA does not.
free((char *)GetFtr(fBuffer));

That’s it. It’s easy, fast, powerful, and safe. It also works with structures, so you can easily have your DAappPrefs available in all functions. If you want to see how it works in a real DA, have a look at the thumbboardDA code.

Related posts:

  1. Fix padding issues in structs
  2. malloc and free for Palm OS
  3. With the Speed of the ARM
  4. On defining multiple pointers in one line
  5. Debugging with decoy printfs

3 Responses to “Globals in DAs”

  1. Just saw an error in step 7

    it says:
    char *Buffer=GetFtr(fBuffer);

    should be:
    char *Buffer=(char *)GetFtr(fBuffer);

    Sorry about that!

  2. Very nice, Peter!

  3. Hi,
    thank you all!

    Best regards
    Tam Hanna

Leave a Reply

(required)

(required)

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Subscribe without commenting

© 2013 TamsPalm - the Palm OS / web OS Blog Suffusion theme by Sayontan Sinha