About PBNI

PBNI is a standard programming interface that enables developers to extend the functionality of PowerBuilder. Using PBNI, you can create extensions to PowerBuilder -- nonvisual, visual, and marshaler extensions -- and embed the PowerBuilder virtual machine (PBVM) into C++ applications. Through the Java Native Interface (JNI) and PBNI, Java applications can also communicate with the PBVM.

Code samples

This documentation contains two complete but very simple examples that illustrate some basic principles of using the PowerBuilder Native Interface (PBNI): Nonvisual extension example and Creating a PowerBuilder object to be called from C++. For more real-world examples, see the PBNI section of the PowerBuilder Code Samples website at https://community.appeon.com/index.php/codeexchange/powerbuilder.

The following diagram illustrates the two-way communication, with both PowerBuilder extensions and external applications, that PBNI provides for the PBVM. As the diagram shows, a PowerBuilder extension communicates with the PBVM through the IPB_Session interface, and the PBVM communicates with the extension through an interface derived from IPBX_UserObject.

C++ and Java extensions communicate with the PBVM through the IPB_VM and IPB_Session interfaces.

Figure: Interaction between the PBVM and external applications and extensions

Understanding PowerBuilder extensions

A PowerBuilder extension is just what its name suggests: an extension to PowerBuilder functionality provided by you, by a third party, or by Appeon. All PowerBuilder extensions communicate with the PBVM through an interface called IPB_Session. This interface and other PBNI objects and interfaces are described in The elements of PBNI.

PowerBuilder provides its own extensions, including a PBDOM XML parser and classes. In future releases, Appeon might develop more new features as PBNI extensions instead of embedding them in the PowerBuilder VM (PBVM), so that the size of the PBVM can be minimized. Extensions are also available from third party contributors; for the latest samples and utilities, see the PBNI section of the PowerBuilder Code Samples website at https://community.appeon.com/index.php/codeexchange/powerbuilder.

Nonvisual extensions

The most frequently used type of PowerBuilder extension is a nonvisual extension. Nonvisual extensions provide a way to call C and C++ functions from PowerBuilder with more flexibility than the previous solution of declaring a function in a script. They also allow you to use object-oriented techniques when working with external objects.

A nonvisual extension is a DLL, written in C++, that exposes one or more native classes and/or global functions. Classes are used in a PowerBuilder application as though they were class user objects created in PowerBuilder -- a native class is simply a PowerScript class that is implemented in C++. Global functions in an extension are used like global functions declared in the Function painter.

Nonvisual extensions allow you to use datatypes in C++ that map to standard PowerBuilder datatypes. PBNI provides predefined datatypes that map to PowerBuilder datatypes, so that you can use PowerBuilder datatypes when you invoke the methods of the native class, and the native class can use predefined types to call back into PowerBuilder. For more information about predefined types, see PBNI Types and Return Values

You can use native classes to call back into the PBVM from the C++ code and trigger PowerBuilder events and invoke functions. You can also call external functions that require callback functions. For example, if your PowerBuilder application uses an extension that is a SAX XML parser, the SAX parser can send information back to the PowerBuilder application about the items it has encountered in the XML document that it is parsing. In response, the PowerBuilder application can send back instructions on how to handle those items.

Possible uses for a nonvisual extension include:

  • A wrapper for a Component Object Model (COM) component that references a user-defined COM interface that cannot be mapped to a PowerBuilder datatype

  • A PowerBuilder interface for database backups and administration using the SQL Anywhere dbtools (which require callback functions)

  • Wrappers for any open source C++ libraries that provide standard utilities

PowerBuilder extensions run faster than standard PowerBuilder user objects because they are compiled in native machine code instead of PowerBuilder pseudocode (Pcode). PBNI complies with the C++ specification, so well-programmed code is portable at the source code level.

Visual extensions

Visual extensions can be used as if they were PowerBuilder visual user objects -- you can place them in windows or on other visual controls. Visual extensions allow you to create a subclass of the Windows procedure (winproc) of a visual component so that you can use the latest "look and feel" for your applications.

Marshaler extensions

Marshaler extensions act as bridges between PowerBuilder and other components, such as CORBA components. PowerBuilder provides a marshaler extension for creating clients for EJB components running in any J2EE-compliant application server. Other techniques for calling EJBs from PowerBuilder do not provide a standard way to marshal PowerBuilder requests to other components and unmarshal the result back to PowerBuilder.

Embedding the PBVM in a C++ application

Many PowerBuilder users have developed sophisticated custom class user objects that handle intensive database operations or other functionality. Such objects can already be used in external applications. However, limitations on the use of some datatypes and of overloaded functions, as well as other coding restrictions, diminishes the value of this technique.

To have direct access to a custom class user object running in the PBVM, and to take advantage of PBNI functions for data access and exchange, you can load the PBVM in the C++ application, create a session, and invoke the custom class user object's functions from the external application.

Communication between the PBVM and a C++ application is based primarily on two interfaces: IPB_VM and IPB_Session.

Interacting with Java

To call Java classes from PowerBuilder, you can build a marshaler extension that invokes Java methods through JNI. You can also use JNI to allow Java to call into PowerBuilder through C or C++.