OLE automation routines in BASIC and C++
You can implement OLE automation routines in any language. This section shows you how to implement OLE automation routines using BASIC or C++ as two sample languages.
The following table shows the mapping of OLE automation types to data types in BASIC and C++.
SQL Type | OLE Automation Type | BASIC Type | C++ Type |
---|---|---|---|
SMALLINT | short | Integer | short |
INTEGER | long | Long | long |
REAL | float | Single | float |
FLOAT or DOUBLE | double | Double | double |
DATE, TIME, TIMESTAMP | DATE | Date | DATE |
CHAR(n) | BSTR | String | BSTR |
CHAR(n) FOR BIT DATA | SAFEARRAY[unsigned char] | Byte() | SAFEARRAY |
VARCHAR(n) | BSTR | String | BSTR |
VARCHAR(n) FOR BIT DATA | SAFEARRAY[unsigned char] | Byte() | SAFEARRAY |
LONG VARCHAR | BSTR | String | BSTR |
LONG VARCHAR FOR BIT DATA | SAFEARRAY[unsigned char] | Byte() | SAFEARRAY |
BLOB(n) | BSTR | String | BSTR |
BLOB(n) FOR BIT DATA | SAFEARRAY[unsigned char] | Byte() | SAFEARRAY |
GRAPHIC(n), VARGRAPHIC(n), LONG GRAPHIC, DBCLOB(n) | BSTR | String | BSTR |
OLE Automation in BASIC
To implement OLE automation routines in BASIC, you need to use the BASIC data types corresponding to the SQL data types mapped to OLE automation types.
bcounter
,
which is created with the BASIC programming language: Public Sub increment(output As Long, _
indicator As Integer, _
sqlstate As String, _
fname As String, _
fspecname As String, _
sqlmsg As String, _
scratchpad() As Byte, _
calltype As Long)
OLE Automation in C++
increment
,
which is created with the C++ programming language: STDMETHODIMP Ccounter::increment (long *output,
short *indicator,
BSTR *sqlstate,
BSTR *fname,
BSTR *fspecname,
BSTR *sqlmsg,
SAFEARRAY **scratchpad,
long *calltype );
HRESULT increment ([out] long *output,
[out] short *indicator,
[out] BSTR *sqlstate,
[in] BSTR *fname,
[in] BSTR *fspecname,
[out] BSTR *sqlmsg,
[in,out] SAFEARRAY (unsigned char) *scratchpad,
[in] long *calltype);
You
can use the ODL description to specify whether a parameter is an input
([in]
), output ([out]
), or input/output
([in,out]
) parameter. For an OLE automation routine,
the routine input parameters and input indicators are specified as [in]
parameters,
and routine output parameters and output indicators as [out] parameters.
For the routine trailing arguments, sqlstate
is an [out]
parameter, fname
and fspecname
are [in]
parameters, scratchpad
is
an [in,out]
parameter, and calltype
is
an [in]
parameter.
OLE automation defines the
BSTR data type to handle strings. BSTR is defined as a pointer to
OLECHAR: typedef OLECHAR *BSTR
. For allocating and
freeing BSTRs, OLE imposes the rule that the called routine frees
a BSTR passed in as a by-reference parameter before routine assigns
the parameter a new value. The same rule applies for one-dimensional
byte arrays that are received by the called routine as SAFEARRAY**
.
The following list contains OLE imposed rules on parameters:
[in]
parameters: The database manager allocates and frees[in]
parameters.[out]
parameters: The database manager passes in a pointer to NULL. The[out]
parameter must be allocated by the routine that is called and is freed by the database manager.[in,out]
parameters: The database manager initially allocates[in,out]
parameters. They can be freed and reallocated by the routine that is called. As is true for[out]
parameters, the database manager frees the final returned parameter.
All other parameters are passed as pointers. The database manager allocates and manages the referenced memory.
OLE automation provides a set of data manipulation functions for dealing with BSTRs and SAFEARRAYs.
The following C++ routine returns the first 5 characters of a CLOB input parameter:
// UDF DDL: CREATE FUNCTION crunch (CLOB(5k)) RETURNS CHAR(5)
STDMETHODIMP Cobj::crunch (BSTR *in, // CLOB(5K)
BSTR *out, // CHAR(5)
short *indicator1, // input indicator
short *indicator2, // output indicator
BSTR *sqlstate, // pointer to NULL
BSTR *fname, // pointer to function name
BSTR *fspecname, // pointer to specific name
BSTR *msgtext) // pointer to NULL
{
// Allocate BSTR of 5 characters
// and copy 5 characters of input parameter
// out is an [out] parameter of type BSTR, that is,
// it is a pointer to NULL and the memory does not have to be freed.
// Database manager will free the allocated BSTR.
*out = SysAllocStringLen (*in, 5);
return NOERROR;
};
An
OLE automation server can be implemented as creatable single-use or creatable
multi-use. When an OLE automation server is implemented as creatable
single-use, each client (that is, a FENCED process) that connects
with the CoGetClassObject
function to an OLE automation
object uses its own instance of a class factory, and run a new copy
of the OLE automation server. When an OLE automation server is implemented
as creatable multi-use, many clients connect to the same
class factory. In an OLE automation server that is implemented as creatable
multi-use, each instantiation of a class factory is supplied
by an already running copy of the OLE server. If there are no copies
of the OLE server running, a copy is automatically started to supply
the class object. The choice between single-use and multi-use OLE
automation servers is yours, when you implement your automation server.
A single-use server can provide better performance.