Ignore:
Timestamp:
Sep 7, 1999, 7:57:55 PM (26 years ago)
Author:
phaller
Message:

Fix: WINE_StringFromCLSID is needed in other modules, too

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/win/wine/obj_base.h

    r680 r856  
    1 /* $Id: obj_base.h,v 1.9 1999-08-25 11:24:09 sandervl Exp $ */
     1/* $Id: obj_base.h,v 1.10 1999-09-07 17:54:57 phaller Exp $ */
    22/*
    3  * This file defines the macros and types necessary to define COM interfaces, 
     3 * This file defines the macros and types necessary to define COM interfaces,
    44 * and the three most basic COM interfaces: IUnknown, IMalloc and IClassFactory.
    55 */
     
    8686    return !(guidOne == guidOther);
    8787}
    88 #endif 
     88#endif
    8989
    9090
     
    9393 */
    9494/*
    95  * The goal of the following set of definitions is to provide a way to use the same 
    96  * header file definitions to provide both a C interface and a C++ object oriented 
    97  * interface to COM interfaces. The type of interface is selected automatically 
    98  * depending on the language but it is always possible to get the C interface in C++ 
     95 * The goal of the following set of definitions is to provide a way to use the same
     96 * header file definitions to provide both a C interface and a C++ object oriented
     97 * interface to COM interfaces. The type of interface is selected automatically
     98 * depending on the language but it is always possible to get the C interface in C++
    9999 * by defining CINTERFACE.
    100100 *
    101101 * It is based on the following assumptions:
    102102 *  - all COM interfaces derive from IUnknown, this should not be a problem.
    103  *  - the header file only defines the interface, the actual fields are defined 
     103 *  - the header file only defines the interface, the actual fields are defined
    104104 *    separately in the C file implementing the interface.
    105105 *
    106  * The natural approach to this problem would be to make sure we get a C++ class and 
     106 * The natural approach to this problem would be to make sure we get a C++ class and
    107107 * virtual methods in C++ and a structure with a table of pointer to functions in C.
    108  * Unfortunately the layout of the virtual table is compiler specific, the layout of 
    109  * g++ virtual tables is not the same as that of an egcs virtual table which is not the 
    110  * same as that generated by Visual C+. There are workarounds to make the virtual tables 
     108 * Unfortunately the layout of the virtual table is compiler specific, the layout of
     109 * g++ virtual tables is not the same as that of an egcs virtual table which is not the
     110 * same as that generated by Visual C+. There are workarounds to make the virtual tables
    111111 * compatible via padding but unfortunately the one which is imposed to the WINE emulator
    112112 * by the Windows binaries, i.e. the Visual C++ one, is the most compact of all.
    113113 *
    114  * So the solution I finally adopted does not use virtual tables. Instead I use inline 
     114 * So the solution I finally adopted does not use virtual tables. Instead I use inline
    115115 * non virtual methods that dereference the method pointer themselves and perform the call.
    116116 *
     
    146146 *
    147147 * Comments:
    148  *  - The ICOM_INTERFACE macro is used in the ICOM_METHOD macros to define the type of the 'this' 
    149  *    pointer. Defining this macro here saves us the trouble of having to repeat the interface 
    150  *    name everywhere. Note however that because of the way macros work, a macro like ICOM_METHOD1 
    151  *    cannot use 'ICOM_INTERFACE##_VTABLE' because this would give 'ICOM_INTERFACE_VTABLE' and not 
     148 *  - The ICOM_INTERFACE macro is used in the ICOM_METHOD macros to define the type of the 'this'
     149 *    pointer. Defining this macro here saves us the trouble of having to repeat the interface
     150 *    name everywhere. Note however that because of the way macros work, a macro like ICOM_METHOD1
     151 *    cannot use 'ICOM_INTERFACE##_VTABLE' because this would give 'ICOM_INTERFACE_VTABLE' and not
    152152 *    'IDirect3D_VTABLE'.
    153  *  - ICOM_METHODS defines the methods specific to this interface. It is then aggregated with the 
     153 *  - ICOM_METHODS defines the methods specific to this interface. It is then aggregated with the
    154154 *    inherited methods to form ICOM_IMETHODS.
    155  *  - ICOM_IMETHODS defines the list of methods that are inheritable from this interface. It must 
    156  *    be written manually (rather than using a macro to generate the equivalent code) to avoid 
     155 *  - ICOM_IMETHODS defines the list of methods that are inheritable from this interface. It must
     156 *    be written manually (rather than using a macro to generate the equivalent code) to avoid
    157157 *    macro recursion (which compilers don't like).
    158  *  - The ICOM_DEFINE finally declares all the structures necessary for the interface. We have to 
     158 *  - The ICOM_DEFINE finally declares all the structures necessary for the interface. We have to
    159159 *    explicitly use the interface name for macro expansion reasons again.
    160  *    Inherited methods are inherited in C by using the IDirect3D_METHODS macro and the parent's 
    161  *    Xxx_IMETHODS macro. In C++ we need only use the IDirect3D_METHODS since method inheritance 
     160 *    Inherited methods are inherited in C by using the IDirect3D_METHODS macro and the parent's
     161 *    Xxx_IMETHODS macro. In C++ we need only use the IDirect3D_METHODS since method inheritance
    162162 *    is taken care of by the language.
    163  *  - In C++ the ICOM_METHOD macros generate a function prototype and a call to a function pointer 
    164  *    method. This means using once 't1 p1, t2 p2, ...' and once 'p1, p2' without the types. The 
    165  *    only way I found to handle this is to have one ICOM_METHOD macro per number of parameters and 
     163 *  - In C++ the ICOM_METHOD macros generate a function prototype and a call to a function pointer
     164 *    method. This means using once 't1 p1, t2 p2, ...' and once 'p1, p2' without the types. The
     165 *    only way I found to handle this is to have one ICOM_METHOD macro per number of parameters and
    166166 *    to have it take only the type information (with const if necessary) as parameters.
    167  *    The 'undef ICOM_INTERFACE' is here to remind you that using ICOM_INTERFACE in the following 
    168  *    macros will not work. This time it's because the ICOM_CALL macro expansion is done only once 
    169  *    the 'IDirect3D_Xxx' macro is expanded. And by that time ICOM_INTERFACE will be long gone 
     167 *    The 'undef ICOM_INTERFACE' is here to remind you that using ICOM_INTERFACE in the following
     168 *    macros will not work. This time it's because the ICOM_CALL macro expansion is done only once
     169 *    the 'IDirect3D_Xxx' macro is expanded. And by that time ICOM_INTERFACE will be long gone
    170170 *    anyway.
    171  *  - You may have noticed the double commas after each parameter type. This allows you to put the 
    172  *    name of that parameter which I think is good for documentation. It is not required and since 
    173  *    I did not know what to put there for this example (I could only find doc about IDirect3D2), 
     171 *  - You may have noticed the double commas after each parameter type. This allows you to put the
     172 *    name of that parameter which I think is good for documentation. It is not required and since
     173 *    I did not know what to put there for this example (I could only find doc about IDirect3D2),
    174174 *    I left them blank.
    175  *  - Finally the set of 'IDirect3D_Xxx' macros is a standard set of macros defined to ease access 
    176  *    to the interface methods in C. Unfortunately I don't see any way to avoid having to duplicate 
    177  *    the inherited method definitions there. This time I could have used a trick to use only one 
     175 *  - Finally the set of 'IDirect3D_Xxx' macros is a standard set of macros defined to ease access
     176 *    to the interface methods in C. Unfortunately I don't see any way to avoid having to duplicate
     177 *    the inherited method definitions there. This time I could have used a trick to use only one
    178178 *    macro whatever the number of parameters but I prefered to have it work the same way as above.
    179  *  - You probably have noticed that we don't define the fields we need to actually implement this 
    180  *    interface: reference count, pointer to other resources and miscellaneous fields. That's 
    181  *    because these interfaces are just that: interfaces. They may be implemented more than once, in 
    182  *    different contexts and sometimes not even in Wine. Thus it would not make sense to impose 
     179 *  - You probably have noticed that we don't define the fields we need to actually implement this
     180 *    interface: reference count, pointer to other resources and miscellaneous fields. That's
     181 *    because these interfaces are just that: interfaces. They may be implemented more than once, in
     182 *    different contexts and sometimes not even in Wine. Thus it would not make sense to impose
    183183 *    that the interface contains some specific fields.
    184184 *
     
    199199 *        HRESULT (*fnCreateViewport)(IDirect3D* me, LPDIRECT3DVIEWPORT* a, IUnknown* b);
    200200 *        HRESULT (*fnFindDevice)(IDirect3D* me, LPD3DFINDDEVICESEARCH a, LPD3DFINDDEVICERESULT b);
    201  *    }; 
     201 *    };
    202202 *
    203203 *    #ifdef ICOM_CINTERFACE
     
    216216 *
    217217 * Comments:
    218  *  - IDirect3D only contains a pointer to the IDirect3D virtual/jump table. This is the only thing 
    219  *    the user needs to know to use the interface. Of course the structure we will define to 
     218 *  - IDirect3D only contains a pointer to the IDirect3D virtual/jump table. This is the only thing
     219 *    the user needs to know to use the interface. Of course the structure we will define to
    220220 *    implement this interface will have more fields but the first one will match this pointer.
    221  *  - The code generated by ICOM_DEFINE defines both the structure representing the interface and 
    222  *    the structure for the jump table. ICOM_DEFINE uses the parent's Xxx_IMETHODS macro to 
    223  *    automatically repeat the prototypes of all the inherited methods and then uses IDirect3D_METHODS 
     221 *  - The code generated by ICOM_DEFINE defines both the structure representing the interface and
     222 *    the structure for the jump table. ICOM_DEFINE uses the parent's Xxx_IMETHODS macro to
     223 *    automatically repeat the prototypes of all the inherited methods and then uses IDirect3D_METHODS
    224224 *    to define the IDirect3D methods.
    225  *  - Each method is declared as a pointer to function field in the jump table. The implementation 
    226  *    will fill this jump table with appropriate values, probably using a static variable, and 
     225 *  - Each method is declared as a pointer to function field in the jump table. The implementation
     226 *    will fill this jump table with appropriate values, probably using a static variable, and
    227227 *    initialize the lpvtbl field to point to this variable.
    228  *  - The IDirect3D_Xxx macros then just derefence the lpvtbl pointer and use the function pointer 
    229  *    corresponding to the macro name. This emulates the behavior of a virtual table and should be 
     228 *  - The IDirect3D_Xxx macros then just derefence the lpvtbl pointer and use the function pointer
     229 *    corresponding to the macro name. This emulates the behavior of a virtual table and should be
    230230 *    just as fast.
    231  *  - This C code should be quite compatible with the Windows headers both for code that uses COM 
     231 *  - This C code should be quite compatible with the Windows headers both for code that uses COM
    232232 *    interfaces and for code implementing a COM interface.
    233233 *
     
    253253 *        public: inline HRESULT FindDevice(LPD3DFINDDEVICESEARCH a, LPD3DFINDDEVICERESULT b)
    254254 *            { return ((IDirect3D*)t.lpvtbl)->fnFindDevice(this,a,b); };
    255  *    }; 
     255 *    };
    256256 *
    257257 * Comments:
    258  *  - In C++ IDirect3D does double duty as both the virtual/jump table and as the interface 
    259  *    definition. The reason for this is to avoid having to duplicate the mehod definitions: once 
    260  *    to have the function pointers in the jump table and once to have the methods in the interface 
    261  *    class. Here one macro can generate both. This means though that the first pointer, t.lpvtbl 
    262  *    defined in IUnknown,  must be interpreted as the jump table pointer if we interpret the 
    263  *    structure as the the interface class, and as the function pointer to the QueryInterface 
    264  *    method, t.fnQueryInterface, if we interpret the structure as the jump table. Fortunately this 
     258 *  - In C++ IDirect3D does double duty as both the virtual/jump table and as the interface
     259 *    definition. The reason for this is to avoid having to duplicate the mehod definitions: once
     260 *    to have the function pointers in the jump table and once to have the methods in the interface
     261 *    class. Here one macro can generate both. This means though that the first pointer, t.lpvtbl
     262 *    defined in IUnknown,  must be interpreted as the jump table pointer if we interpret the
     263 *    structure as the the interface class, and as the function pointer to the QueryInterface
     264 *    method, t.fnQueryInterface, if we interpret the structure as the jump table. Fortunately this
    265265 *    gymnastic is entirely taken care of in the header of IUnknown.
    266  *  - Of course in C++ we use inheritance so that we don't have to duplicate the method definitions. 
    267  *  - Since IDirect3D does double duty, each ICOM_METHOD macro defines both a function pointer and 
    268  *    a non-vritual inline method which dereferences it and calls it. This way this method behaves 
    269  *    just like a virtual method but does not create a true C++ virtual table which would break the 
    270  *    structure layout. If you look at the implementation of these methods you'll notice that they 
    271  *    would not work for void functions. We have to return something and fortunately this seems to 
     266 *  - Of course in C++ we use inheritance so that we don't have to duplicate the method definitions.
     267 *  - Since IDirect3D does double duty, each ICOM_METHOD macro defines both a function pointer and
     268 *    a non-vritual inline method which dereferences it and calls it. This way this method behaves
     269 *    just like a virtual method but does not create a true C++ virtual table which would break the
     270 *    structure layout. If you look at the implementation of these methods you'll notice that they
     271 *    would not work for void functions. We have to return something and fortunately this seems to
    272272 *    be what all the COM methods do (otherwise we would need another set of macros).
    273  *  - Note how the ICOM_METHOD generates both function prototypes mixing types and formal parameter 
    274  *    names and the method invocation using only the formal parameter name. This is the reason why 
     273 *  - Note how the ICOM_METHOD generates both function prototypes mixing types and formal parameter
     274 *    names and the method invocation using only the formal parameter name. This is the reason why
    275275 *    we need different macros to handle different numbers of parameters.
    276  *  - Finally there is no IDirect3D_Xxx macro. These are not needed in C++ unless the CINTERFACE 
     276 *  - Finally there is no IDirect3D_Xxx macro. These are not needed in C++ unless the CINTERFACE
    277277 *    macro is defined in which case we would not be here.
    278  *  - This C++ code works well for code that just uses COM interfaces. But it will not work with 
    279  *    C++ code implement a COM interface. That's because such code assumes the interface methods 
     278 *  - This C++ code works well for code that just uses COM interfaces. But it will not work with
     279 *    C++ code implement a COM interface. That's because such code assumes the interface methods
    280280 *    are declared as virtual C++ methods which is not the case here.
    281281 *
     
    312312 *
    313313 * Comments:
    314  *  - We first define what the interface really contains. This is th e_IDirect3D structure. The 
     314 *  - We first define what the interface really contains. This is th e_IDirect3D structure. The
    315315 *    first field must of course be the virtual table pointer. Everything else is free.
    316  *  - Then we predeclare our static virtual table variable, we will need its address in some 
     316 *  - Then we predeclare our static virtual table variable, we will need its address in some
    317317 *    methods to initialize the virtual table pointer of the returned interface objects.
    318  *  - Then we implement the interface methods. To match what has been declared in the header file 
    319  *    they must take a pointer to a IDirect3D structure and we must cast it to an _IDirect3D so that 
     318 *  - Then we implement the interface methods. To match what has been declared in the header file
     319 *    they must take a pointer to a IDirect3D structure and we must cast it to an _IDirect3D so that
    320320 *    we can manipulate the fields. This is performed by the ICOM_THIS macro.
    321321 *  - Finally we initialize the virtual table.
     
    673673    ICOM_VTABLE(IUnknown)* lpvtbl;
    674674#if defined(ICOM_USE_COM_INTERFACE_ATTRIBUTE) && !defined(ICOM_CINTERFACE)
    675 } __attribute__ ((com_interface)); 
     675} __attribute__ ((com_interface));
    676676#else
    677677};
     
    867867 */
    868868#ifdef __WINE__
    869 HRESULT WINE_StringFromCLSID(const CLSID *id, LPSTR);
     869HRESULT WIN32API WINE_StringFromCLSID(const CLSID *id, LPSTR);
    870870#endif
    871871
Note: See TracChangeset for help on using the changeset viewer.