Home > Language Reference > Statements
Declare Statement
Declares an external procedure or function.
Syntax
To declare an external procedure:
{ Public | Private } Declare Sub Name ( [ ArgList ] ) Trap Trap [ { , | StdSel | HostSel | StackSel } Selector ]
To declare an external function:
{ Public | Private } Declare Function Name ( [ ArgList ] ) As Type Trap Trap [ { , | StdSel | HostSel | StackSel } Selector ]
| Parameter | Description |
| Name | Procedure or function name. |
| ArgList | List of the arguments the external procedure accepts. |
| Type | Return type of the external function. |
| Trap | Trap number (see below). |
| Selector | Selector number (see below). |
Remarks
The Declare statement allows the declaration of an external function written in C, located in a shared library or in the operating system itself. It is then possible to call this function like any other function with the Call statement.
This functionality can be used to call native Palm OS® functions that are not encapsulated by the HB++ execution library, but also, when your application requires particular performance, to call low level functions written in C.
Using this statement requires good knowledge of how to pass parameters to C functions, and should only be used by experienced programmers.
The Name parameter indicates the name of the procedure or function declared. It is this identifier that will be used to call the external function from your program, and does not have to be identical to the original name of the C function: in fact, HB++ does not have any means of knowing its original name, and uses only the trap and selector numbers to find the correct library function.
It is also possible to declare the same function several times under different names, which can prove useful when your C function is expecting generic parameters of type void * for example: you can declare the relevant function as many times as necessary, under different names and with different argument lists. For example, the Palm OS® function StrLen expects a pointer to a character string. You can declare it:
Public Declare Function StrLenChar(ByRef s As String) As Integer Trap &HA0C7 Public Declare Function StrLenAddr(ByVal a As Long) As Integer Trap &HA0C7
The first function could be called directly with a parameter of type String whilst the second could be called with a parameter of type Long corresponding to the address of a character string. In both cases, the same external function is called, the trap number being identical.
The Trap parameter should be a constant expression whose value is between 40960 and 65535 inclusive. It indicates the function number to call in the external library. Some functions also require a selector number, which can be either passed through the D2 register or either on the stack. This selector number as well as its type can be specified using the optional Selector parameter, preceded by a comma or by one of the following keywords :
| Keyword | Description |
| StdSel | Same as a comma. Indicates that the selector number should be passed to the function through the D2 register. This is the most common case. |
| HostSel | Indicates that the selector number should be passed on the stack as an extra parameter to the function. This mode is notably used to declare functions provided by the Palm OS Emulator whose prototypes can be found in the HostControl.h header file. |
| StackSel | Indicates that the selector number should be passed on the stack as an extra parameter to the function, but that this parameter should be popped by the callee instead of being popped by the caller. This mode is used for some licensee SDK such as Handspring Treo 600. |
If you declare a C function in a library you have written, you can choose these numbers freely, and should simply make sure that they are the same both in the library and in your HB++ program. If on the other hand you declare a native PalmOS® function, you should refer to the C header files in the Palm OS® SDK to find out these numbers and how selectors should be specified. Note that this point may require good C knowledge.
The Type parameter indicates, in the case of a function, the type of the value returned by the external function. Only basic and enumerated types are allowed here. It is not possible to return a value of type String, Variant or an object because an external function has no way to create and return data of these types. In addition to basic types, you can also use the Pointer keyword which is strictly equivalent to the type Long but indicates to the compiler that the external function returns the value to the A0 register instead of the D0 register. This particularity is necessary because of the function return convention of the CodeWarrior™ and GCC compilers on the Motorola® 68000. For example, the Palm OS® MemPtrNew function should be declared as below:
Public Declare Function MemPtrNew(ByVal lSize as Long) As Pointer Trap &HA013
If you do not plan to use the return value, you can also declare an external function as a procedure. The value returned is simply ignored by HB++, and the code generated is more compact and faster.
The table below summarises the types authorised for the Type parameter with their equivalent in C.
| HB++ Return Type | C Return Type | Remarks |
| Boolean | Boolean, UInt8, char, unsigned char... | See note (1) below. |
| Byte | UInt8, unsigned char... | |
| Integer | Int16, short, int... | |
| Long | Int32, long... | |
| Single | float | See note (2) below. |
| Double | double | See notes (2) and (3) below. |
| Date | UInt32, unsigned long... | See note (4) below. |
| Pointer | Any pointer type | |
| Any enumerated type | Any type of the same size as the enumerated type | See note (5) below. |
(1) If the value returned by the external function is zero, this is interpreted as False. Any other values is interpreted as True.
(2) Some special values defined by the IEEE 754 standard are not managed by the HB++ mathematical library, and cannot therefore be returned by the external function. Refer to the introduction page on Mathematical Functions for more information.
(3) HB++ is expecting values of type Double in the pair of registers D0 - D1. Some C compilers do not adhere to this convention (noteably CodeWarrior™ with which the Palm OS® operating system is compiled), and uses a hidden pointer parameter to return values whose length is greater than 4 bytes.
(4) The value returned by the external function is interpreted as the number of seconds elapsed since 1 January 1904. Because the HB++ execution library cannot handle dates after 31 December 2031, the external function should not return a value greater than 4 039 372 800.
(5) Depending on the value of the constants making up an enumerated type, this occupies 1, 2 or 4 bytes, and is equivalent respectively to a Byte, Integer, or Long which means that the external function must return a UInt8, Int16, or Int32. Refer to the page on Enumerations for more information.
Finally, the ArgList parameter describes the list of parameters expected by the external function. As with a function or procedure declaration, each parameter should be separated by a comma, and can contain ByVal or ByRef. It is also possible to specify optional parameters. Refer to the description of the Sub statement for more information on the syntax of declaring parameters.
For basic and enumerated types, using the ByVal keyword causes the parameter value to be passed to the external function, whilst using the ByRef keyword causes a pointer to be passed. For types String and StreamMemory, a pointer to the first byte of the data is passed whichever convention is specified. Other types like Variant for example or object variables cannot be passed to external procedures. The table below summarises the types with their equivalent in C.
| Parameter | Passed | Expected Parameter | Remarks |
| Boolean | ByVal | Boolean, UInt8, char, unsigned char... | See note (1) below |
| Boolean | ByRef | Boolean *, UInt8 *, char *, unsigned char *... | See note (1) below |
| Byte | ByVal | UInt8, unsigned char... | |
| Byte | ByRef | Uint8 *, unsigned char *... | |
| Integer | ByVal | Int16, int, short... | |
| Integer | ByRef | Int16 *, int *, short *... | |
| Long | ByVal | Int32, long... | |
| Long | ByRef | Int32 *, long *... | |
| Single | ByVal | float | See note (2) below |
| Single | ByRef | float * | See note (2) below |
| Double | ByVal | double | See note (2) below |
| Double | ByRef | double * | See note (2) below |
| Date | ByVal | UInt32, unsigned long | See note (3) below |
| Date | ByRef | UInt32 *, unsigned long * | See note (3) below |
| String | ByVal ByRef | char * | See note (4) below |
| StreamMemory | ByVal ByRef | void * or any type of pointer | |
| Any enumerated type | ByVal | Any type of the same size as the enumerated type. | |
| Any enumerated type | ByRef | A pointer of any type of the same size as the enumerated type | |
(1) If the parameter is True, the external function receives the value 1. If the parameter is False, the external function receives the value 0.
(2) Some special values defined by the IEEE 754 standard are not managed by the HB++ mathematical library, and cannot therefore be received by the external function. Refer to the introduction page on Mathematical Functions for more information.
(3) The value received by the external function is interpreted as the number of seconds elapsed since 1 January 1904.
(4) The external function receives a pointer to the first character in the string. If an empty string is passed, the external function receives a NULL pointer.
(5) The external function receives a pointer to the first byte of the data, even if the StreamMemory is empty. To pass a NULL pointer, pass the value Nothing.
When you pass a pointer to an external function using arguments of type String or StreamMemory, you should take into account the fact that the memory block passed is allocated and maintained by HB++. The external function must not attempt to destroy it or modify its size. In the same way, if the external function must modify the data contained in the memory block, you must make sure that it is large enough. In the case of a String, you can use the Space function for example.
For further information on shared libraries and communication between HB++ and the C language, refer to the Shared Libraries chapter in the Programmer's Guide. You can also see refer to the MathLib Sinus sample.
System requirements
| System | Minimal version | Remarks |
| Palm OS | Palm OS 3.0 | N/A |