Step 2: Define the classes and functions in the extension
Your C++ code must expose two standard methods that enable PowerBuilder to recognize each native class and create instances of the class. One of these methods is PBX_GetDescription.
Use PBX_GetDescription to pass the descriptions of classes and global functions in the PowerBuilder extension to PowerBuilder. Every extension must export this method. Importing the PBX or DLL file into a PBL converts the description of the extension into PowerScript and adds it to the PBL as source code. The keyword native in the source code indicates that the PowerBuilder type was defined in an extension.
All the classes or global functions in an extension module are passed in a single description. The examples that follow illustrate how you define classes and functions in a description. For the full syntax, see PBX_GetDescription.
Describing nonvisual classes
Nonvisual classes can inherit from the NonVisualObject PowerBuilder system class or any of its descendants. While a native class can inherit from a user–defined user object, Sybase recommends that you use only system classes. Each native class can provide several functions, subroutines, and events.
The following example shows how you use the PBX_GetDescription method in the C++ code for an extension that includes three nonvisual classes. ClassName1 inherits from NonVisualObject, ClassName2 inherits from Exception, and ClassName3 inherits from Transaction. All three classes must be in a single description passed by PBX_GetDescription:
PBXEXPORT LPCTSTR PBXCALL PBX_GetDescription()
{
static const TCHAR desc[] = {
// Description begins here
"class ClassName1 from NonVisualObject\n"
"function integer objectFunction(integer a[])\n"
"subroutine objectSubroutine(integer ai_ref)\n"
"event integer eventName(integer b)\n"
"end class\n"
"class ClassName2 from Exception\n"
"function integer objectFunction(readonly
integer ai)\n"
"subroutine objectSubroutine(integer arg)\n"
"event integer eventName(integer arg)\n"
"end class\n"
"class ClassName3 from Transaction\n"
"function integer objectFunction(integer arg)\n"
"subroutine objectSubroutine(integer arg)\n"
"event integer eventName(integer arg)\n"
"end class\n"
// Description ends here
};
return desc;
}
Describing visual classes
Visual native classes can inherit only from the UserObject PowerBuilder system class. The PowerBuilder VM considers any class that inherits from UserObject to be a visual class. All other native classes are considered to be nonvisual classes. For more information about how to describe visual classes, see "Creating and using a visual extension".
Describing global functions
An extension can include global functions as well as classes. This example shows a description for two global functions:
"globalfunctions \n" \
"function int g_1(int a, int b)\n" \
"function long g_2(long a, long b)\n" \
"end globalfunctions\n"
The syntax and usage of global functions defined in an extension are the same as for global functions defined in the Function painter in PowerBuilder.
Like global functions in PowerScript, global functions in a PowerBuilder extension cannot be overloaded.
Using forward declarations
PowerBuilder extensions can provide multiple classes. A class can reference any class that is defined earlier in the description, but if it references a class defined later in the description, you must provide a forward declaration. This example shows a description that includes forward declarations for two classes, nativeclass_1 and nativeclass_2, that reference each other. This example also demonstrates that a single description can include global functions as well as classes:
"forward\n" \
"class nativeclass_1 from nonvisualobject\n"\
"class nativeclass_2 from nonvisualobject\n"\
"end forward\n" \
"class nativeclass_1 from nonvisualobject \n" \
"function int add(nativeclass_2 a, int b)\n" \
"function int sub(int a, int b)\n" \
"end class \n" \
"class nativeclass_2 from nonvisualobject \n" \
"function int add(nativeclass_1 a, int b)\n" \
"function int sub(int a, int b)\n" \
"end class \n"
"globalfunctions \n" \
"function int g_1(int a, int b)\n" \
"function long g_2(long a, long b)\n" \
"end globalfunctions\n"