Defining the component interface
When you build a PowerBuilder custom class user object as a
COM or MTS component, the functions and optionally the instance
variables defined for the object appear in the component interface. PowerBuilder generates
an IDL file that defines a COM class and a single interface for
each custom class user object contained in the server, as well as
a type library name and an associated ID for the PowerBuilder COM
server.
Methods and data types
Functions
Each PowerBuilder COM object supports a single interface that
exposes a method for each user-defined public function in the custom
class user object.
The function’s return value is represented by an
additional retval argument. For example, if an object has these
user object functions:
1 |
f_addtwo (long al_num1, long al_num2) returns long |
1 |
f_getinfo (REF string as_name, REF integer ai_age, |
1 |
REF character ac_gender) returns integer |
These member functions are generated in the IDL file:
1 |
HRESULT f_addtwo( [in] long al_num1, |
1 |
[in] long al_num2, [out, retval] long * retval ); |
1 |
HRESULT f_getinfo( [in, out] BSTR * as_name, |
1 |
[in, out] short * ai_age, [in, out] unsigned |
1 |
char * ac_gender, [out, retval] short * retval ); |
Instance variables
Since COM objects never expose their data, public instance
variables in the custom class user object can be represented in
the COM object as interface methods for getting and setting the
variable value. You can specify that variable accessor methods will
be exposed in the interface in the Project wizard or on the Objects
property page in the Project painter.
If the public variable is writable, the put method will be
exposed. For private and protected variables and variables declared
as privateread or protectedread and privatewrite or protectedwrite,
no methods are generated. If the variable is publicly readable,
the get method will be exposed. For example, if an object has these
instance variables:
1 |
public string is_name |
1 |
private integer ii_a |
1 |
public privatewrite string is_label |
1 |
constant real lr_pi = 3.14159265 |
These are the methods that are generated in the IDL file:
1 |
[id(4), propget] HRESULT is_name([out,retval] |
1 |
BSTR *is_name); |
1 |
[id(4), propput] HRESULT is_name([in] |
1 |
BSTR is_name); |
1 |
[id(1), propget] HRESULT is_label([out,retval] |
1 |
BSTR *is_label); |
1 |
[id(6), propget] HRESULT lr_pi( [out,retval] |
1 |
float * lr_pi); |
Data type mappings
PowerBuilder data types map to COM data types as follows:
PowerBuilder data type | COM data type (variants) |
---|---|
Boolean | Variant_BOOL |
Character | Unsigned char |
Integer | Short |
UnsignedInteger | Unsigned short |
Long | Long |
UnsignedLong | Unsigned long |
Real | Float |
Double | Double |
Decimal | Double |
String | BSTR |
Date | DATE |
Time | DATE |
DateTime | DATE |
Blob | SAFEARRAY (Unsigned char) |
Arrays (PowerBuilder data type) | SAFEARRAY (COM data type) |
ResultSet | LPDISPATCH |
Custom class user objects* | LPDISPATCH |
Any | Not supported |
Global structures | Not supported |
OLEObjects | Not supported |
* Custom class user objects must be created
within the same client in the same COM apartment (that is, in the
same thread)
Restrictions on coding
There are some elements that you cannot use in your code when
you plan to deploy a user object as a COM or MTS component.
No overloaded functions
COM does not support overloaded functions in an interface
to a COM object. Each function in the user object (and its ancestors)
must have a unique name. PowerBuilder COM objects have a single interface,
and multiple functions with the same name but different signatures
would require multiple interfaces.
How ancestor variables and ancestor functions
are represented
When you generate a PowerBuilder COM object from a descendent
user object, the public instance variables and functions of both
the ancestor and the descendant are represented in the COM object.
The fact that some of the component methods were derived from the
ancestor object is transparent. Because of the restriction on overloaded
functions described above, functions in descendent objects can override
functions in the ancestor but they cannot overload them.
Data types for arguments and return values
The methods associated with a nonvisual object that you deploy
as a COM object can take arguments that use the following data types:
- Standard OLE automation
data types - Custom class (nonvisual) user objects
COM component methods cannot take arguments or return values
that use PowerBuilder structures or the Any data type. Functions defined
on a PowerBuilder nonvisual object that take an Any variable as an
argument or return an Any variable can be called from code that
is local to that object; however, these functions cannot be accessed
by clients or other COM components.
The arguments to a component method cannot include visual
objects (such as windows or menus) or most system types (such as
the Transaction object or the DataStore object). The only system
type supported is the ResultSet object.
The return value of a component method can be of any standard
data type. The return value can also be a custom class (nonvisual)
user object.
COM/MTS validation
If you are designing a custom class user object that you plan
to deploy as a COM or MTS component, you can have PowerBuilder warn
you when you use code elements that are not valid in COM or MTS.
COM/MTS validation checks for overloaded functions
and checks public instance variables and public functions for system
types, visual types, structures, and Any variables.
In the User Object painter, select Design>COM/MTS
Validation from the menu bar. When you save the object, the Compiler
Information Messages dialog box lists warnings such as the following:
1 |
Information C0197: Component Validation |
1 |
Warning C0198: illegal COM/MTS type: 'any' arg type for function: 'of_badfunc' |
1 |
Warning C0198: illegal COM/MTS type: 'window' arg type for function: 'of_badfunc' |
Validation is associated with the object you are editing,
not with the User Object painter. When you reopen an object, it
has the same validation state as when you closed it. New objects
are created with no validation items checked.
Wizards enable validation If you create a new user object using the COM/MTS
Start or Object wizard, validation is enabled by default.