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
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.
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.
/* 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_valueA 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.