COM and Uniface Parameter Data Types
Converting Uniface parameter data types to and from the COM environment has both a static and dynamic nature. When you export a COM Interface DLL, the data types of the signature definitions must be matched to the appropriate COM types, taking into account the user’s implementation selections. At runtime, both Uniface and COM allow the user to pass variants for parameters, so the connector can dynamically convert data types, within reason.
Export COM Interface DLL
The COM data types that you can use must comply with the IDispatch interface, which is based upon the data types that can be transported through a COM VARIANT structure. The COM type names listed in the table are the VARIANT union tag values:
Uniface 4GL data type | Default exported COM data type | Visual Basic Type |
---|---|---|
String | VT_BSTR (a Unicode string) | String |
Handle | VT_DISPATCH | Object |
Boolean | VT_BOOL | Bool |
Numeric | VT_I4 (a 4-byte integer) | Long |
Float | VT_R8 (an 8-byte float) | Double |
Date | VT_DATE, time part is 00:00:00. | Date |
Time | VT_DATE, date part is today. | Date |
Datetime | VT_DATE | Date |
Linear Date | VT_DATE | Date |
Linear Time | VT_DATE | Date |
Linear DateTime | VT_DATE | Date |
Raw | VT_ARRAY | VT_UI1 (an array of bytes) | Dim VAR() As Byte |
Image | A standard COM IPicture object | IPicture |
Entity | See Call-Out | ADOR.Recordset |
Occurrence | Treated as a one-record UTYPE_ENTITY | ADOR.Recordset |
These are only the default conversions applied at COM Interface DLL export time. It is possible for the user to change the service after the COM Interface DLL is exported and it is also possible for a COM client to call a service without adhering to the definition in the type library.
Additional COM data types can be used if, for example, a Uniface type should be mapped to a different COM data type. These non-default values are available in the drop-down list in the Define Parameter dialog in the Signature Editor.
Linear Date/Time Handling
The default data type in the Signature Editor for Linear values is COM’s VT_DATE. If the user chooses to convert a Uniface LinearDate or LinearDateTime to a numeric-based type, for example, VT_R8 or VT_I4. The epoch used is the Uniface epoch (the day before 01-Jan-0000), not the COM epoch (30-Dec-1899).
The Uniface epoch is based upon a value of 1.0 on 01-Jan-0000. The COM epoch is based upon a value of 1.0 on 31-Dec-1899. Uniface expresses 31-Dec-1899 as 693961.0.
If the developer passes a Uniface LinearDate to a Visual Basic Date, and Visual Basic subsequently converts it to a Double. A different result is returned than if the LinearDate is passed directly to a Double.
If the user chooses to convert a Uniface LinearTime to a numeric-based type, such as VT_R8 or VT_I4, the result will be a floating-point value that contains the fractional part of a day. For example, 06:00 hours is expressed as 0.25 and 12-noon is expressed as 0.5.
Call-Out
A connector converts whatever data is passed from the client Uniface service to a data type that is expected by the called COM object. This happens independently of the 4GL signature or the imported type library.
For call-out, the activate statement uses the Signature Editor definitions to initially validate the parameters, then the COM connector completes the activate request by using the COM method interface published by the COM object.
It is not normally necessary for the Signature Editor definitions to exactly match the COM interface, as the COM connector will convert the Uniface data types as required. However, the parameter directions (IN, OUT, INOUT) must be set correctly in the Signature Editor. In addition, Uniface parameters that are actually Uniface instances (and therefore must be treated as COM objects), must be properly indicated in the Signature Editor with the Handle data type and the classification name that this parameter maps to.
The UTYPE_IMAGE type can only be converted to:
- A COM IPicture object
- A VT_ARRAY of VT_UI1 (an array of bytes)
When exporting a service operation into a type library, a call-out entity parameter (UTYPE_ENTITY) is always exposed as a standard COM ActiveX Data Objects (ADO) Recordset object. A Recordset is similar to a Uniface entity; it has multiple records of fields, a current record, and you can insert and remove occurrences. ADO is a high-level standard for data access in the Microsoft environment.
The COM client can choose not to adhere to the type library definitions and call the Uniface operation with another COM data type.
Call-in
It is customary for COM clients to adhere to the interface definition that is in the type library, but it is not required. So-called ‘scripting’ environments do not require any type information on the client side. For this reason, the call-in data mapping within the connector needs to be complete.
The UTYPE_IMAGE data type requires an image, consequently, the COM connector expects a VT_DISPATCH or VT_UNKNOWN that points to an IPicture to be passed to the Uniface parameter. An array of bytes is also permitted.
Entity parameters are handled in a manner similar to that of the call-out situation.
COM arrays can be mapped to either a Uniface entity or a Uniface string list. The type of the Uniface formal parameter determines the exact conversion.
COM operation implementation
The following examples show the implementation for two operations, both of which return the number one. The first operation is implemented in Uniface, the second operation is implemented in Microsoft Visual Basic.
Call a Uniface service that returns a value 1
The assignment file contains the following setting:
KURB040UF = $COM:KURB040UF CLASS=KURB.KURB040UF
The signature for the service KURB040UF contains the following definitions:
implementation: COM;
operation: COM_1;
parameter: VALUE (numeric, out)
implementation: Uniface Service (default)
Form KURB040, Button Uniface, detail trigger:
variables
Handle kurb040uf
;RT testcase 10
endvariables
newinstance "kurb040uf", kurb040uf
;RT testcase 11
kurb040uf->com_1(u_return)
Service KURB040UF:
operation COM_1 params numeric value : out endparams putmess "%%$componentname%%% operation COM_1 called" value = 1 end ; operation COM_1
Call a Visual Basic object that returns a value 1
The assignment file contains the following setting:
KURB040VB = $COM:KURB040VB CLASS=KURBTESTSVB.KURB040VB
The signature for the service KURB040VB contains the following definitions:
Implementation: COM; operation: COM_1; parameter: VALUE (numeric, out)
Form KURB040, Button Visual Basic, detail trigger:
trigger detail newinstance "kurb040vb", kurb040vb variables Handle kurb040uf endvariables kurb040vb->com_1(u_return) end
Visual Basic code:
Public Function com_1(value As Long) As Long Open "kurb040vb.log" For Append As #1 Write #1, Now Write #1, "Case 2: kurbtestsvb.kurb040vb.com_1 called" value = 1 com_1 = 0 Close #1 End Function
Excel
The following example shows how to call a specific cell in an Excel spreadsheet, and retrieve its value. The assignment file contains the following setting:
KURB040ME = $COM:KURB040ME CLASS=KURB.KURB040ME
The Signature Editor contains the following definitions:
Component: KURB040ME; implementation: COM; operation: VISIBLE; parameter X (boolean, IN) literalname: VISIBLE.SET operation: WORKBOOKS; parameter: X, connected to KURB040MEWB operation: CELLS; parameter: ROW (numeric, IN) parameter: COL (string, IN) operation: QUIT; parameter: none signature: KURB040MEWB; implementation: COM; operation: OPEN parameter: FILENAME (string, IN) operation: CLOSE parameter: none
Call a specific Excel spreadsheet cell
This example illustrates how to call a specific cell in an Excel spreadsheet, and retrieve its value.
The assignment file contains the following setting:
KURB040ME = $COM:KURB040ME CLASS=KURB.KURB040ME
The Signature Editor contains the following definitions:
Component: KURB040ME; implementation: COM; operation: VISIBLE; parameter X (boolean, IN) literalname: VISIBLE.SET operation: WORKBOOKS; parameter: X, connected to KURB040MEWB operation: CELLS; parameter: ROW (numeric, IN) parameter: COL (string, IN) operation: QUIT; parameter: none Signature: KURB040MEWB; implementation: COM; operation: OPEN parameter: FILENAME (string, IN) operation: CLOSE parameter: none
The form KURB040 is painted with a Command Button called ’Excel’. The detail trigger of this button contains the following ProcScript:
; activate application newinstance "kurb040me",$1 ; set property visible=true $1->visible(1) ; activate method workbooks, returning an object reference $1->workbooks($2) ; open a spreadsheet $2->open("kurb_com.xls") ; retrieve the value in cell A1 into $status $1->cells(1,"A") ; activate close method, closing the workbook $2->close() ; activate quit method, removing the application $1->quit()
Spreadsheet kurb_com.xls, Sheet KURBO40, Cell A1 contains the value "1".
Call-in from Visual Basic
The following example illustrates how to call a
Uniface operation (com_callin
) in a service (kurb041s
) from a
Visual Basic subroutine.
Private Sub Command1_Click() Dim value as Long Dim result as Long Dim svc As kurb041s Dim rc As Long Set svc = New [Uniface components kurb_call_in].kurb041s result = svc.com_callin(value) End Sub