| By Roy Kiesler | Article Rating: |
|
| January 9, 2004 12:00 PM EST | Reads: |
22,419 |
The PowerBuilder Native Interface (PBNI) is a standard C++ programming interface that allows developers to extend the PowerScript language with C++ classes and to call PowerScript functions from C++ applications.
Modeled after the Java Native Interface (JNI), PBNI provides a native vehicle that extends the functionality of PowerBuilder to that of the C++ programming language.
In Part 2 (Vol. 10, issue 12), we created your first PBNI class and worked with PBNI objects. In Part 3, we'll trigger PowerBuilder events, call PowerScript system functions from within a PBS, and discuss accessing and manipulation arrays.
A PBX can trigger PowerScript events on any PowerBuilder object, including itself. The process of triggering PowerBuilder events on other objects is very similar to that of invoking object functions. Listing 6 in Part 2 could easily be modified to trigger an event instead of invoking a user-object function by substituting two lines of code.
First, the method lookup:
// function syntax - replace with event syntax below
pbmethodID mid = pud->session->GetMethodID(
cls, "onnewwindow", PBRT_FUNCTION, "LSSS" );
// event syntax
pbmethodID mid = pud->session->GetMethodID(
cls, "newwindow", PBRT_EVENT, "LSSS" );
Next, the method invocation:
// function syntax - replace with event syntax below
pud->session->InvokeObjectFunction( pud->object, mid, &ci );
// event syntax
pud->session->TriggerEvent( pud->object, mid, &ci );
Invoking events on the PBX object involves a few more steps, as follows:
1. Add an event declaration to the class description in PBX_GetDescription(); for example:
"event ue_mypbnievent( int arg1, string arg2 ) "
2. In PowerBuilder, inherit a new NVO from the PBX, for example:
n_cpp_hello
and add PowerScript code to the exposed events. Save this new derived class as n_cpp_derivedhello.
3. When using the PBX, instantiate the derived object whose event handler functions have now been written as follows:
pbniobj = CREATE n_cpp_derivedhello
Tip
The C++ source code for this example contains both event and function syntax form. To see them both in action, you'll have to toggle the commented-out lines, recompile, and re-create a PBD. The PowerBuilder client code requires no changes.
PBNI Global Functions
The code examples we've covered up to this point were based on a PowerBuilder class that inherits from the NonVisualObject class. However, there are cases in which instantiating a custom class in order to invoke a frequently used function seems an unnecessary overhead. Although we could declare and instantiate a global NVO and use its functionality throughout the duration of the application session, a more elegant solution would be to expose the PBNI interface as a set of global functions that more seamlessly extend the PowerScript syntax.
The example we'll examine next is based on the popular demand for bitwise operations in PowerBuilder. Bitwise operations are commonly used in the Windows API; for example, setting multiple styles on a given window.
As mentioned earlier in this article, in order to export PBNI functions as global PowerScript functions, your PBX needs to:
- Declare the global functions in the PBX_GetDescription() method:
"globalfunctions "
/* PBX_Bitwise */
" function ulong BitwiseOr( ulong arg1, ulong arg2 ) "
" function ulong BitwiseXor( ulong arg1, ulong arg2 ) "
" function ulong BitwiseAnd( ulong arg1, ulong arg2 ) "
" function ulong BitwiseNot( ulong arg ) "
" function ulong BitwiseLeftShift( ulong arg, uint pos ) "
" function ulong BitwiseRightShift( ulong arg, uint pos ) "
"end globalfunctions " - Export the PBX_InvokeGlobalFunction() function, as shown in Listing 1.
Calling PowerScript System Functions from Within a PBX
In addition to being able to invoke global and object functions (and events), a PBX can also invoke PowerScript system functions. The process of triggering PowerBuilder system functions is very similar to that of invoking object functions. Listing 2 illustrates the process of calling the PowerScript Asc() function. Figure 2 shows the results in the PowerBuilder client application.
Accessing and Manipulation Arrays
The PBNI SDK divides arrays into two main categories: simple and object. Within each category, arrays can be either bounded (have a fixed sized) or unbounded (have a variable size).
The pbarray data type is the basic PBNI representation for arrays of both types. Consider the following PBX function declaration:
subroutine sortIntegerArray( REF int numbers[] )
When this function is invoked from PowerBuilder, the PBX class retrieves the PowerBuilder array of integers as follows:
if ( ci->pArgs->GetAt(0)->IsNull() )
pbxr = PBX_E_INVALID_ARGUMENT;
else if ( !ci->pArgs->GetAt(0)->IsArray() ||
!ci->pArgs->GetAt(0)->IsByRef() || )
{
pbxr = PBX_E_INVALID_ARGUMENT;
}
else
{
pbarray pbaNums = ci->pArgs->GetAt(0)->GetArray();
}
The IPB_Session interface provides a set of rudimentary methods for creating an array object, obtaining information about it, and accessing its content. Listing 3 demonstrates the use of some of these methods, combined with the use of the PBArrayInfo structure.
Published January 9, 2004 Reads 22,419
Copyright © 2004 SYS-CON Media, Inc. — All Rights Reserved.
Syndicated stories and blog feeds, all rights reserved by the author.
More Stories By Roy Kiesler
Roy Kiesler, a senior lead consultant with Percussion Software in Massachusetts, has worked with PowerBuilder for the past seven years. He now spends most of his time with XML and Java. A winner of the 2001 TeamSybase MVP award, Roy has been a member of TeamSybase since 1999.

