Foxhound is the better* Database Monitor for SQL Anywhere.
*better: More thorough, more relevant, more effective.
...more Alerts, more All Clears, more details, more control in your hands.


Breck Carter
Last modified: May 29, 1996
mail to: bcarter@bcarter.com



Pointer Arithmetic in PowerBuilder!

Here's a tip that should warm the hearts of C and Assembler programmers who miss the ability to directly manipulate memory pointers.

It also provides a useful service by answering the question: "How can I get DOS environment variables into my PowerBuilder program? When I call GetDOSEnvironment all I get back is the first value."

The DOS environment block is actually a series of zero-terminated strings concatenated together, followed by an extra zero byte to mark the end of the block. When you call the Windows function GetDOSEnvironment to put this block into a PowerBuilder string, none of the PowerScript string functions or operators can see past the zero byte marking the end of the first string. The data's all there but you can't get at it.

Over the years there have been a number of solutions to this problem but none as slick as the one from Eric Aling of Cypres Informatisering in The Netherlands. If you declare GetDOSEnvironment as returning a long value instead of a string, you can directly manipulate this block pointer to "step over" the zero bytes to get at the other environment strings. Figure 1 shows the end result: A window that lets you type the name of any DOS environment variable and see its value.

Figure 1: Display DOS Environment Variables

The second half of Eric's solution involves converting this long pointer to a string. This can be done using a poorly-documented feature of PowerBuilder: Look up TriggerEvent in the Help to read about string ( long, "address" ).

Figure 2 shows how the environment block can be searched for a particular variable. It uses pointer arithmetic (actually just ordinary arithmetic on a long variable) to find successive values.

Figure 2: f_get_environment_value

/*
Description: Get value of a DOS environment variable.
   The following External Function declaration is
   required: function long GetDOSEnvironment()
   library "krnl386.exe"

Argument:
   as_variable_name - Name of DOS environment variable.

Returns:
   string - Value of DOS environment variable.

Example:
   ls_path = f_get_environment_value ( "path" )
*/

long    ll_pointer
string  ls_environment_string
string  ls_variable_value
boolean lb_not_done

ls_variable_value = "" // until proven otherwise

// Get the pointer to the DOS environment block.

ll_pointer = GetDOSEnvironment()

// Get the first environment string by treating the
// long pointer as the "address of a string".
// The assignment will stop copying characters at
// the first zero terminator byte.

ls_environment_string = string ( ll_pointer, "address" )

// Check to see if the environment block is empty.

if ls_environment_string = "" then
   lb_not_done = false
else
   lb_not_done = true
end if

// Loop until the variable is found or
// the block is exhausted.

do while lb_not_done

   // Check for "NAME=".

   if upper ( left &
         ( ls_environment_string, &
           len ( as_variable_name ) + 1 ) ) &
    = upper ( as_variable_name ) + "=" then

      // Copy the value and stop the loop.

      ls_variable_value &
          = mid ( ls_environment_string, &
                  len ( as_variable_name ) + 2 )
      lb_not_done = false

   else

      // Increment the pointer to next string in
      // the block by stepping over the current
      // string and its zero byte terminator.

      ll_pointer = ll_pointer &
         + len ( ls_environment_string ) + 1

      // Get the next string.

      ls_environment_string &
         = string ( ll_pointer, "address" )

      // Check if the block is exhausted.

      if ls_environment_string = "" then
         lb_not_done = false
      end if

   end if

loop

return ls_variable_value
A final word of warning is in order here: Overuse of string ( long, "address" ) can be dangerous to your program's health! That's because the PowerBuilder runtime environment is a very dynamic thing and its designers did not expect that programs would directly manipulate pointer values. It's a technique that should be strictly used as a last resort as in searching the DOS environment block.


Breck Carter can be reached by phone at (416) 763-5200 or via email at bcarter@bcarter.com.