Contents
This is a draft concerning how COM and UNO types are mapped to types of another environment. The term mapping, refers to how COM type library information is represented by UNO type library information and vice versa. So technically, this document is about converting type library data.
2.1 Restrictions and ConventionsCOM components are usually distributed with a type library rather than IDL files. The TLB (type library) does not contain all the information that is provided by IDL files. These are:
To generate UNO type library information, one would use the COM TLB and hence have to deal with ambiguities caused by insufficient information. These ambiguities mainly affect pointer parameters. To solve this problem, all of those types are mapped to one special UNO type, that contains additional information, which is to be supplied by the programmer. COM uses Unicode Strings:
COM allows the partial transmission of array data. The COM to UNO mapping does not take this into account; instead, arrays are always transmitted as a whole. The bridge uses the UNO type library to marshal calls from UNO to COM. Therefore,
the used COM interfaces must be represented in that library. To resolve ambiguities
and to make programming easier, the UNO TLB contains custom type information,
such as pointer parameter,
2.2 Predefined and Base Types
[1] void is allowed when used with 2.3 void and the iid_is attribute
When this method is called from UNO, then the caller knows the Interface which
is to be returned. In this case, the bridge knows the interface by the parameter
Assuming the bridge knows what parameter contains the If one generates UNO type infos from a COM TLB, then the
In MIDL, it is also possible to tag in parameters with the
In this example, the any contains the interface along with its type
description. The
In this case, the bridge also needs to know what parameter contains the
This function can be treated like the case where both parameters are out parameters. Here is a summary of reasonable combinations:
Unfortunately, the
Because of this, pointers are ambiguous, they could be normal pointers or those
attributed with When a COM interface containing 2.4 ArraysCOM uses a variety of arrays, such as: fixed, varying, conformant, varying,
and conformant arrays, as well as Fixed ArraysFixed arrays have a predefined size and are used as in C.
Varying ArraysVarying arrays have a fixed size; however, depending on additional arguments and attributes, only a part of the array is transmitted.
Conformant ArraysConformant arrays can vary in size which is specified by a separate argument.
Sized Pointers
Other ArraysArrays can be both conformant and varying. Multidimensional ArraysCOM arrays can have multiple dimensions, for example:
Arrays and the COM TLB The array attributes, which specify a portion of an array that is to be transmitted,
cause the MIDL compiler to generate a TLB with a parameter description that
contains the If the array has an attribute which specifies the size of the array, then the
parameter description in the TLB contains the Arrays can also be represented by pointers as in C, and the MIDL array attributes
can be applied as well. The parameter description contains When a Multidimensional arrays whose dimensions all have a fixed size are contained in the TLB as multidimensional arrays with the respective dimensions and sizes. If the size of a dimension has been omitted in MIDL then the TLB contains a pointer instead, for example:
Only the use of fixed arrays results in a proper parameter description. The
parameter description then contains the type Mapping It would be desirable to map MIDL arrays to UNO IDL sequences, because the
The generated UNO type information could look like this ( C++ representation):
If this method is called in UNO then the bridge must provide all additional parameters for the COM function. The size and length could be derived from the length of the sequence. Additionally, the bridge needs to know what parameter receives which value. Unfortunately, that information is not given because those array attributes are not contained in the COM type library. If an array is not fixed then the parameter or member is described as pointer by the TLB. Because of the ambiguities caused by that, pointers are mapped to a special UNO type that can contain all those ambiguous types. See chapter Mapping for Pointers for a description of that type. The function in the example above would be mapped to this UNO function:
Although the COM TLB identifies Fixed arrays are identified as such by the COM TLB. They are mapped to UNO arrays of a fixed size.
Examples:
2.5 StringStrings can occur in various ways in COM interfaces. This specification only takes those strings into account that are identified as strings by the COM TLB. That excludes strings which are actually arrays as in counted arrays:
Strings are described as such only when they are either Strings can also be specified with the Mapping ASCII and Unicode strings are mapped to UNO strings, only when they were declared
with the string attribute. That is, the COM TLB contains the information that
they are in fact strings.
2.6 typedefTypedefs are very similar to C typedefs. The MIDL compiler generates headers which use the defined types and includes the typedef statement. The generated TLB only contains information about
A type is a Whenever the COM TLB contains a 2.7 UnionMIDL knows two union types, encapsulated unions and nonencapsulated unions. The
MIDL compiler generates a struct from an encapsulated union that contains a discriminant
and the union. Nonencapsulated unions need an additional parameter or member that
contains the discriminant. The discriminant is referred to by the
The COM TLB does not contain the switch_is attribute. MappingEncapsulated unions are contained in the COM TLB, as a struct with a member that acts as discriminant and another member that is a union. Because a union always needs a discriminant so that MIDL can produce proper marshaling code, one can infer that a struct with a union and only one additional member is an encapsulated union.
switch_is
attribute). Therefore, the COM2UNO converter cannot omit the discriminant member
or parameter. The union itself is mapped to an any. The bridge knows when a parameter
or member is a union (custom type information), and can map the any appropriately.
Example:
Mapping:
2.8 ConstantsThe COM TLB does not contain information about const values. Instead, those values are directly used wherever applied in MIDL, for example, a fixed array. Therefore, there is no mapping required. 2.9 EnumeratorsEnumerations in MIDL are much alike UNO enumerations, because MIDL uses a C like syntax, the enums are typedef'ed .
Mapping:
2.10 StructMIDL structures can be mapped to UNO IDL structures. The members are mapped according to the rules for the mapping of those members. Structs are often declared within a typedef statement.
A COM TLB only contains a Mapping:
2.11 PointersMIDL uses three different pointer types: reference pointers, unique pointers, and
full pointers, which are used for in, out, and in/out parameter. See the chapter about
parameters for more details.
The optimum UNO mapping would be:
Instead one needs to substitute the long by a type that can hold all possible types that are described as pointers by the COM TLB.
The
One certainly does not have to supply all the information, because the bridge could use some logic and inference rules to take some of the load off the programmer. As mentioned, COM uses three different pointer types with different characteristics.
The
The
A COM_Ptr would possibly contain an any that holds all the
different types. It
does not need a flag indicating that the bridge has to interpret the data as pointer,
because the bridge knows that, from custom UNO type information and by the fact
that a When the function is called, the program would set the any so that
it points
to a certain position within the string. As the bridge receives the call, it would
usually convert the UNO string into a The bridge therefore, needs to be informed about a possible correlation between
parameters. The programmer could put additional data into the 2.12 OLE Automation Types
2.13 GUIDThe
The fields: 2.14 InterfaceNaming Conventions Mapped COM interfaces are decorated with a COM_ prefix, for example,
Function and parameter names remain the same. FunctionsMapped COM functions have the same name and parameter names; however, the return type changes, and the parameter types may change as well. COM functions return a Often a parameter has the attribute retval, which means that the parameter
is the actual return value. If the function is used by Visual Basic or one uses
some kind of wrapper, as provided by the The parameter types are mapped to UNO types according to the specification. COM interface functions are called with the The Base Interface A mapped COM interface must have all the characteristics of an UNO interface.
This means, that it has to inherit from
When an UNO client calls On return, the out parameter
InheritanceUNO, as well as, COM interfaces support single inheritance. Whenever a COM interface inherits an interface then the mapped UNO interface does the same. The inherited interface must be mapped as well. IDispatch Mapped COM interfaces could be used in event sink implementations, that is,
they get called from COM, then they must have a mapping of The table summarizes the importance of a mapping of
This matter is still worth discussing. As for now, the
2.15 In, Out, In / Out ParametersThis chapter shows what information is needed for the bridge to do a proper conversion of all the different parameter types. In Parameters COM in parameters can be recognized by the The bridge converts UNO parameters and creates pointers to the converted values,
as necessary. The knowledge of what the level of indirection is can be obtained
from the COM TLB (custom type information). Because of the ambiguity between
pointers and arrays, one has to pass a special UNO construct, that can act as
those types. That construct could be, for example, an any, so the type
(array or not) is implicitly given. There is no need to pass information about
the fact whether the value is a pointer, because the bridge knows that from
the COM TLB. The bridge might still need additional information, for example, whether the pointer
is a
All in parameters, except for pointers or arrays are mapped as specified.
Pointers
and arrays have to be mapped to the same UNO type ( In/Out ParametersIn/out parameters have the flags PARAMFLAG_FIN and PARAMFLAG_FOUT set. For conversions, the bridge has to convert parameters in both directions. Hence, the considerations for in as well as for out parameters apply. Unlike pure out parameters, in/out parameter can be caller allocated, even if the pointer has two and more levels.
The datatype for in/out parameters could look like this:
Out ParametersThe COM specification says: out parameters are allocated by the caller and freed by the callee. The bridge acts, then, as a caller and thus has to free the results. This statement is quite confusing, because lots of COM interfaces, as can be found in the include directory of Visual Studio, pass arrays as out parameters and have the function fill in the data. That filling in could hardly be called allocating data. An example:
Out parameters are marked with the Another issue is arrays, which are allocated by the callee and whose size is passed as an out parameter; that is, the caller does not know the size until return of the function:
The bridge cannot figure out what parameter contains the size, because this information cannot be obtained from COM TLBs; therefore, the bridge must be explicitly told what parameter contains the size of the array. If a pointer of level two or higher is used, then the bridge cannot recognize whether it has to supply the memory or only a pointer; therefore, we need an UNO construct that is used as an out parameter and contains the information. We could use a structure that contains a member which indicates who is responsible for freeing the memory.
In the case an array is passed by reference, then the sequence must have the proper length. This length is used by the bridge to determine the size of the memory which has to be copied from the out parameter into the sequence. Examples: 1. out parameter is *
1b)
2. out parameter is **
2 b)
2c)
The table shows when a value might be caller or callee allocated dependent on the level of indirection of the pointer, described in the COM TLB.
2.16 Mapping for PointersThis mapping combines the mapping of pointers which can be used as in, out, and in/out parameters. The UNO type that is mapped to, must contain the following information:
The meaning of the
The members of
When 2.17 Restrictions with COM interfaces implemented in UNOCOM can have parameters which are only useful with another parameter, that is, they, somehow, bear information about that parameter which is only known at runtime. An example is the C -array whose size is not known at compile time. To realize a mapping of those functions to UNO one has to employ special UNO types that carry some additional information.
Because the dependencies declared by the size_is attribute are not contained
in
the COM TLB, one cannot combine both parameters in UNO (a
The Now lets say that a COM object is being accessed by an UNO client and that
the object supports events. In other words, the client could register an event
sink with the object. The sink object needs to implement the COM interface
that is described by the COM TLB ( attribute Usually, COM event interfaces rarely use out parameters, but it might be feasible. The following types do not work with event interfaces:
3.1 ConventionsA COM programmer usually needs header files with type declarations to program
a component. The header files are generated either by the MIDL compiler or through
the 3.2 Base Types
3.3 ConstantsUNO constants cannot be mapped to COM constants by generating a COM TLB.MIDL allows one to declare static or const members of interfaces, and the generated
header, in fact, contains a static variable or a define, but the TLB does not contain
that information. The only way to declare constants would be to use a module,
but that does not correspond to the use of modules along with COM components.
Moreover, the 3.4 EnumeratorsUNO enumerators are mapped to MIDL enumerators. The namescape is merged into the enumeration name.
3.5 StringAn UNO string is mapped to a 3.6 StructStructs are mapped to MIDL structs, according to the specification of each element. The name of MIDL struct contains the namespace.
3.7 UnionUNO unions are mapped to encapsulated unions. ( UNO unions are currently not specified, but might be in the near future.)
3.8 Sequence
3.9 ArraysArrays are mapped to 3.10 Anyanys are mapped to 3.11 Uik
Uik::Data1 ... Uik::Data3 are mapped
to GUID::Data1 ... GUID::Data3, and the members Uik::Data4
and Uik::Data5 are mapped to GUID::Data4.
3.12 TypedefOnly typedefs for
can be mapped to COM TLB typedefs. All other typedefs must be converted so that the new type is substituted by its original type. In fact, structs, enumeration, and unions should always be typedef'ed in the
COM TLB. That is because the 3.13 ExceptionsCOM offers two way of reporting errors, The error handling interfaces instead offer interface based error information.
To support this error reporting mechanism, the bridge must provide implementations
for 3.14 InterfacesNaming Convention A mapped UNO interface keeps it name except for the leading "X"
which is substituted by an "I". The namespace is not reflected by the
name. That poses no risk of ambiguities because COM interfaces are identified
by their FunctionsWhen an interface is mapped, then it's function names, as well as the parameter names, remain the same. The return value is mapped to an out parameter, and exceptions are mapped to
error codes or, if there is no error code specified, they are mapped to
The During run time, the bridge has to map the calling convention from Base Interface A mapped UNO interface inherits
The bridge maps calls on On return, the return value is being mapped to the interface that has been queried
for. In case the any contains a type of InheritanceCOM interfaces support single inheritance. When an UNO interface is mapped that inherits another interface, then the mapped interface does the same.
XInvocation 3.15 In, Out, In / Out ParametersIn parameter are mapped so that they are passed by value. Out and In/Out parameters are passed by reference, for example:
Example:
Currently, it is still unclear how UNO arrays are handled when used as an out parameter.
|

