Contents Index Creating procedures and functions with external calls Passing parameters to external functions

ASA SQL User's Guide
  Using Procedures, Triggers, and Batches
    Calling external libraries from procedures

External function prototypes


This section describes the API for functions in external libraries.

The API is defined by a header file named extfnapi.h, in the h subdirectory of your SQL Anywhere Studio installation directory. This header file handles the platform-dependent features of external function prototypes. The API supercedes a previous API for functions in external libraries.

Declaring the API version 

To notify the database server that the external library is not written using the old API, provide a function as follows:

uint32 extfn_use_new_api( )

The function returns an unsigned 32-bit integer. If the return value is non-zero, the database server assumes that you are not using the old API.

If the function is not exported by the DLL, the database server assumes that the old API is in use. When using the new API, the returned value must be the API version number defined in extfnapi.h.

On NetWare, to notify the database server that the external procedure is written using the new API, your NLM must export either a function called extfn_use_new_api, or a function called name_use_new_api, where name is the name of the NLM. For example, an NLM named external.nlm would export a function external_use_new_api.

Exporting name_use_new_api avoids export name conflicts when more than one external NLM is in use at one time. If the NLM exports a function called name_use_new_api then the CREATE PROCEDURE or CREATE FUNCTION statement must contain the NLM name.

Function prototypes 

The name of the function must match that referenced in the CREATE PROCEDURE or CREATE FUNCTION statement. The function declaration must be as follows:

void function-name( an_extfn_api *apivoid *argument-handle )

The function must return void, and must take as arguments a structure used to pass the arguments, and a handle to the arguments provided by the SQL procedure.

The an_extfn_api structure has the following form:

typedef struct an_extfn_api {
    short (SQL_CALLBACK *get_value)(
                void *          arg_handle,
                a_SQL_uint32    arg_num,
                an_extfn_value *value
                );
    short (SQL_CALLBACK *get_piece)(
                void *          arg_handle,
                a_SQL_uint32    arg_num,
                an_extfn_value *value,
                a_SQL_uint32    offset
                );
    short (SQL_CALLBACK *set_value)(
                void *          arg_handle,
                a_SQL_uint32    arg_num,
                an_extfn_value *value
                short          append
                );
void (SQL_CALLBACK *set_cancel)(
                void *   arg_handle,
                void *   cancel_handle
                );
} an_extfn_api;

The an_extfn_value structure has the following form:

typedef struct an_extfn_value {
    void *            data;
    a_SQL_uint32       piece_len;
    union {
        a_SQL_uint32   total_len;
        a_SQL_uint32   remain_len;
    } len;
    a_SQL_data_type      type;
} an_extfn_value;
Notes 

Calling get_value on an OUT parameter returns the data type of the argument, and returns data as NULL.

The get_piece function for any given argument can only be called immediately after the get_value function for the same argument,

To return NULL, set data to NULL in an_extfn_value.

The append field of set_value determines whether the supplied data replaces (false) or appends to (true) the existing data. You must call set_value with append=FALSE before calling it with append=TRUE for the same argument. The append field is ignored for fixed length data types.

The header file itself contains some additional notes.

The following table shows the conditions under which the functions defined in an_extfn_api return false:

Function Returns 0 when the following is true; else returns 1
get_value() - arg_num is invalid; for example, arg_num is greater than the number of arguments in ext_fn - It is called before the external function call has been properly initialized
get_piece() - arg_num is invalid; for example, arg_num does not correspond to the last get_value. |- The offset is greater than the total length of the value for the arg_num argument. - It is called before the external function call has been properly initialized.
set_value() - arg_num is invalid; for example, arg_num is greater than the number of arguments in ext_fn. - arg_num argument is input only. - The type of value supplied does not match that of the arg_num argument. - It is called before the external function call has been properly initialized.

For more information about the values you can enter in the a_sql_data_type field, see Embedded SQL data types.

For more information about passing parameters to external functions, see Passing parameters to external functions.

Implementing cancel processing 

An external function that expects to be canceled must inform the database server by calling the set_cancel API function. You must export a special function to enable external operations to be canceled. This function must have the following form:

void an_extfn_cancel( void * cancel_handle )

If the DLL does not export this function, the database server ignores any user interrupts for functions in the DLL. In this function, cancel_handle is a pointer provided by the function being cancelled to the database server upon each call to the external function by the set_cancel API function listed in the an_extfn_api structure, above.


Contents Index Creating procedures and functions with external calls Passing parameters to external functions