Ignore:
Timestamp:
Jun 24, 1999, 11:48:07 PM (26 years ago)
Author:
phaller
Message:

Add: Added CoRegisterSurrogate() header (David Raison)

File:
1 edited

Legend:

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

    r94 r184  
    1 /* $Id: obj_base.h,v 1.3 1999-06-10 16:21:52 achimha Exp $ */
     1/* $Id: obj_base.h,v 1.4 1999-06-24 21:48:07 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 */
     
    2121#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
    2222        const GUID name = \
    23         { l, w1, w2, { b1, b2,  b3,  b4,  b5,  b6,  b7,  b8 } }
     23   { l, w1, w2, { b1, b2,  b3,  b4,  b5,  b6,  b7,  b8 } }
    2424#else
    2525#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
     
    2828
    2929#define DEFINE_OLEGUID(name, l, w1, w2) \
    30         DEFINE_GUID(name, l, w1, w2, 0xC0,0,0,0,0,0,0,0x46)
     30   DEFINE_GUID(name, l, w1, w2, 0xC0,0,0,0,0,0,0,0x46)
    3131
    3232#define DEFINE_SHLGUID(name, l, w1, w2) DEFINE_OLEGUID(name,l,w1,w2)
     
    6767    return !(guidOne == guidOther);
    6868}
    69 #endif 
     69#endif
    7070
    7171
     
    7474 */
    7575/*
    76  * The goal of the following set of definitions is to provide a way to use the same 
    77  * header file definitions to provide both a C interface and a C++ object oriented 
    78  * interface to COM interfaces. The type of interface is selected automatically 
    79  * depending on the language but it is always possible to get the C interface in C++ 
     76 * The goal of the following set of definitions is to provide a way to use the same
     77 * header file definitions to provide both a C interface and a C++ object oriented
     78 * interface to COM interfaces. The type of interface is selected automatically
     79 * depending on the language but it is always possible to get the C interface in C++
    8080 * by defining CINTERFACE.
    8181 *
    8282 * It is based on the following assumptions:
    8383 *  - all COM interfaces derive from IUnknown, this should not be a problem.
    84  *  - the header file only defines the interface, the actual fields are defined 
     84 *  - the header file only defines the interface, the actual fields are defined
    8585 *    separately in the C file implementing the interface.
    8686 *
    87  * The natural approach to this problem would be to make sure we get a C++ class and 
     87 * The natural approach to this problem would be to make sure we get a C++ class and
    8888 * virtual methods in C++ and a structure with a table of pointer to functions in C.
    89  * Unfortunately the layout of the virtual table is compiler specific, the layout of 
    90  * g++ virtual tables is not the same as that of an egcs virtual table which is not the 
    91  * same as that generated by Visual C+. There are workarounds to make the virtual tables 
     89 * Unfortunately the layout of the virtual table is compiler specific, the layout of
     90 * g++ virtual tables is not the same as that of an egcs virtual table which is not the
     91 * same as that generated by Visual C+. There are workarounds to make the virtual tables
    9292 * compatible via padding but unfortunately the one which is imposed to the WINE emulator
    9393 * by the Windows binaries, i.e. the Visual C++ one, is the most compact of all.
    9494 *
    95  * So the solution I finally adopted does not use virtual tables. Instead I use inline 
     95 * So the solution I finally adopted does not use virtual tables. Instead I use inline
    9696 * non virtual methods that dereference the method pointer themselves and perform the call.
    9797 *
     
    127127 *
    128128 * Comments:
    129  *  - The ICOM_INTERFACE macro is used in the ICOM_METHOD macros to define the type of the 'this' 
    130  *    pointer. Defining this macro here saves us the trouble of having to repeat the interface 
    131  *    name everywhere. Note however that because of the way macros work, a macro like ICOM_METHOD1 
    132  *    cannot use 'ICOM_INTERFACE##_VTABLE' because this would give 'ICOM_INTERFACE_VTABLE' and not 
     129 *  - The ICOM_INTERFACE macro is used in the ICOM_METHOD macros to define the type of the 'this'
     130 *    pointer. Defining this macro here saves us the trouble of having to repeat the interface
     131 *    name everywhere. Note however that because of the way macros work, a macro like ICOM_METHOD1
     132 *    cannot use 'ICOM_INTERFACE##_VTABLE' because this would give 'ICOM_INTERFACE_VTABLE' and not
    133133 *    'IDirect3D_VTABLE'.
    134  *  - ICOM_METHODS defines the methods specific to this interface. It is then aggregated with the 
     134 *  - ICOM_METHODS defines the methods specific to this interface. It is then aggregated with the
    135135 *    inherited methods to form ICOM_IMETHODS.
    136  *  - ICOM_IMETHODS defines the list of methods that are inheritable from this interface. It must 
    137  *    be written manually (rather than using a macro to generate the equivalent code) to avoid 
     136 *  - ICOM_IMETHODS defines the list of methods that are inheritable from this interface. It must
     137 *    be written manually (rather than using a macro to generate the equivalent code) to avoid
    138138 *    macro recursion (which compilers don't like).
    139  *  - The ICOM_DEFINE finally declares all the structures necessary for the interface. We have to 
     139 *  - The ICOM_DEFINE finally declares all the structures necessary for the interface. We have to
    140140 *    explicitly use the interface name for macro expansion reasons again.
    141  *    Inherited methods are inherited in C by using the IDirect3D_METHODS macro and the parent's 
    142  *    Xxx_IMETHODS macro. In C++ we need only use the IDirect3D_METHODS since method inheritance 
     141 *    Inherited methods are inherited in C by using the IDirect3D_METHODS macro and the parent's
     142 *    Xxx_IMETHODS macro. In C++ we need only use the IDirect3D_METHODS since method inheritance
    143143 *    is taken care of by the language.
    144  *  - In C++ the ICOM_METHOD macros generate a function prototype and a call to a function pointer 
    145  *    method. This means using once 't1 p1, t2 p2, ...' and once 'p1, p2' without the types. The 
    146  *    only way I found to handle this is to have one ICOM_METHOD macro per number of parameters and 
     144 *  - In C++ the ICOM_METHOD macros generate a function prototype and a call to a function pointer
     145 *    method. This means using once 't1 p1, t2 p2, ...' and once 'p1, p2' without the types. The
     146 *    only way I found to handle this is to have one ICOM_METHOD macro per number of parameters and
    147147 *    to have it take only the type information (with const if necessary) as parameters.
    148  *    The 'undef ICOM_INTERFACE' is here to remind you that using ICOM_INTERFACE in the following 
    149  *    macros will not work. This time it's because the ICOM_CALL macro expansion is done only once 
    150  *    the 'IDirect3D_Xxx' macro is expanded. And by that time ICOM_INTERFACE will be long gone 
     148 *    The 'undef ICOM_INTERFACE' is here to remind you that using ICOM_INTERFACE in the following
     149 *    macros will not work. This time it's because the ICOM_CALL macro expansion is done only once
     150 *    the 'IDirect3D_Xxx' macro is expanded. And by that time ICOM_INTERFACE will be long gone
    151151 *    anyway.
    152  *  - You may have noticed the double commas after each parameter type. This allows you to put the 
    153  *    name of that parameter which I think is good for documentation. It is not required and since 
    154  *    I did not know what to put there for this example (I could only find doc about IDirect3D2), 
     152 *  - You may have noticed the double commas after each parameter type. This allows you to put the
     153 *    name of that parameter which I think is good for documentation. It is not required and since
     154 *    I did not know what to put there for this example (I could only find doc about IDirect3D2),
    155155 *    I left them blank.
    156  *  - Finally the set of 'IDirect3D_Xxx' macros is a standard set of macros defined to ease access 
    157  *    to the interface methods in C. Unfortunately I don't see any way to avoid having to duplicate 
    158  *    the inherited method definitions there. This time I could have used a trick to use only one 
     156 *  - Finally the set of 'IDirect3D_Xxx' macros is a standard set of macros defined to ease access
     157 *    to the interface methods in C. Unfortunately I don't see any way to avoid having to duplicate
     158 *    the inherited method definitions there. This time I could have used a trick to use only one
    159159 *    macro whatever the number of parameters but I prefered to have it work the same way as above.
    160  *  - You probably have noticed that we don't define the fields we need to actually implement this 
    161  *    interface: reference count, pointer to other resources and miscellaneous fields. That's 
    162  *    because these interfaces are just that: interfaces. They may be implemented more than once, in 
    163  *    different contexts and sometimes not even in Wine. Thus it would not make sense to impose 
     160 *  - You probably have noticed that we don't define the fields we need to actually implement this
     161 *    interface: reference count, pointer to other resources and miscellaneous fields. That's
     162 *    because these interfaces are just that: interfaces. They may be implemented more than once, in
     163 *    different contexts and sometimes not even in Wine. Thus it would not make sense to impose
    164164 *    that the interface contains some specific fields.
    165165 *
     
    180180 *        HRESULT (*fnCreateViewport)(IDirect3D* me, LPDIRECT3DVIEWPORT* a, IUnknown* b);
    181181 *        HRESULT (*fnFindDevice)(IDirect3D* me, LPD3DFINDDEVICESEARCH a, LPD3DFINDDEVICERESULT b);
    182  *    }; 
     182 *    };
    183183 *
    184184 *    #ifdef ICOM_CINTERFACE
     
    197197 *
    198198 * Comments:
    199  *  - IDirect3D only contains a pointer to the IDirect3D virtual/jump table. This is the only thing 
    200  *    the user needs to know to use the interface. Of course the structure we will define to 
     199 *  - IDirect3D only contains a pointer to the IDirect3D virtual/jump table. This is the only thing
     200 *    the user needs to know to use the interface. Of course the structure we will define to
    201201 *    implement this interface will have more fields but the first one will match this pointer.
    202  *  - The code generated by ICOM_DEFINE defines both the structure representing the interface and 
    203  *    the structure for the jump table. ICOM_DEFINE uses the parent's Xxx_IMETHODS macro to 
    204  *    automatically repeat the prototypes of all the inherited methods and then uses IDirect3D_METHODS 
     202 *  - The code generated by ICOM_DEFINE defines both the structure representing the interface and
     203 *    the structure for the jump table. ICOM_DEFINE uses the parent's Xxx_IMETHODS macro to
     204 *    automatically repeat the prototypes of all the inherited methods and then uses IDirect3D_METHODS
    205205 *    to define the IDirect3D methods.
    206  *  - Each method is declared as a pointer to function field in the jump table. The implementation 
    207  *    will fill this jump table with appropriate values, probably using a static variable, and 
     206 *  - Each method is declared as a pointer to function field in the jump table. The implementation
     207 *    will fill this jump table with appropriate values, probably using a static variable, and
    208208 *    initialize the lpvtbl field to point to this variable.
    209  *  - The IDirect3D_Xxx macros then just derefence the lpvtbl pointer and use the function pointer 
    210  *    corresponding to the macro name. This emulates the behavior of a virtual table and should be 
     209 *  - The IDirect3D_Xxx macros then just derefence the lpvtbl pointer and use the function pointer
     210 *    corresponding to the macro name. This emulates the behavior of a virtual table and should be
    211211 *    just as fast.
    212  *  - This C code should be quite compatible with the Windows headers both for code that uses COM 
     212 *  - This C code should be quite compatible with the Windows headers both for code that uses COM
    213213 *    interfaces and for code implementing a COM interface.
    214214 *
     
    234234 *        public: inline HRESULT FindDevice(LPD3DFINDDEVICESEARCH a, LPD3DFINDDEVICERESULT b)
    235235 *            { return ((IDirect3D*)t.lpvtbl)->fnFindDevice(this,a,b); };
    236  *    }; 
     236 *    };
    237237 *
    238238 * Comments:
    239  *  - In C++ IDirect3D does double duty as both the virtual/jump table and as the interface 
    240  *    definition. The reason for this is to avoid having to duplicate the mehod definitions: once 
    241  *    to have the function pointers in the jump table and once to have the methods in the interface 
    242  *    class. Here one macro can generate both. This means though that the first pointer, t.lpvtbl 
    243  *    defined in IUnknown,  must be interpreted as the jump table pointer if we interpret the 
    244  *    structure as the the interface class, and as the function pointer to the QueryInterface 
    245  *    method, t.fnQueryInterface, if we interpret the structure as the jump table. Fortunately this 
     239 *  - In C++ IDirect3D does double duty as both the virtual/jump table and as the interface
     240 *    definition. The reason for this is to avoid having to duplicate the mehod definitions: once
     241 *    to have the function pointers in the jump table and once to have the methods in the interface
     242 *    class. Here one macro can generate both. This means though that the first pointer, t.lpvtbl
     243 *    defined in IUnknown,  must be interpreted as the jump table pointer if we interpret the
     244 *    structure as the the interface class, and as the function pointer to the QueryInterface
     245 *    method, t.fnQueryInterface, if we interpret the structure as the jump table. Fortunately this
    246246 *    gymnastic is entirely taken care of in the header of IUnknown.
    247  *  - Of course in C++ we use inheritance so that we don't have to duplicate the method definitions. 
    248  *  - Since IDirect3D does double duty, each ICOM_METHOD macro defines both a function pointer and 
    249  *    a non-vritual inline method which dereferences it and calls it. This way this method behaves 
    250  *    just like a virtual method but does not create a true C++ virtual table which would break the 
    251  *    structure layout. If you look at the implementation of these methods you'll notice that they 
    252  *    would not work for void functions. We have to return something and fortunately this seems to 
     247 *  - Of course in C++ we use inheritance so that we don't have to duplicate the method definitions.
     248 *  - Since IDirect3D does double duty, each ICOM_METHOD macro defines both a function pointer and
     249 *    a non-vritual inline method which dereferences it and calls it. This way this method behaves
     250 *    just like a virtual method but does not create a true C++ virtual table which would break the
     251 *    structure layout. If you look at the implementation of these methods you'll notice that they
     252 *    would not work for void functions. We have to return something and fortunately this seems to
    253253 *    be what all the COM methods do (otherwise we would need another set of macros).
    254  *  - Note how the ICOM_METHOD generates both function prototypes mixing types and formal parameter 
    255  *    names and the method invocation using only the formal parameter name. This is the reason why 
     254 *  - Note how the ICOM_METHOD generates both function prototypes mixing types and formal parameter
     255 *    names and the method invocation using only the formal parameter name. This is the reason why
    256256 *    we need different macros to handle different numbers of parameters.
    257  *  - Finally there is no IDirect3D_Xxx macro. These are not needed in C++ unless the CINTERFACE 
     257 *  - Finally there is no IDirect3D_Xxx macro. These are not needed in C++ unless the CINTERFACE
    258258 *    macro is defined in which case we would not be here.
    259  *  - This C++ code works well for code that just uses COM interfaces. But it will not work with 
    260  *    C++ code implement a COM interface. That's because such code assumes the interface methods 
     259 *  - This C++ code works well for code that just uses COM interfaces. But it will not work with
     260 *    C++ code implement a COM interface. That's because such code assumes the interface methods
    261261 *    are declared as virtual C++ methods which is not the case here.
    262262 *
     
    293293 *
    294294 * Comments:
    295  *  - We first define what the interface really contains. This is th e_IDirect3D structure. The 
     295 *  - We first define what the interface really contains. This is th e_IDirect3D structure. The
    296296 *    first field must of course be the virtual table pointer. Everything else is free.
    297  *  - Then we predeclare our static virtual table variable, we will need its address in some 
     297 *  - Then we predeclare our static virtual table variable, we will need its address in some
    298298 *    methods to initialize the virtual table pointer of the returned interface objects.
    299  *  - Then we implement the interface methods. To match what has been declared in the header file 
    300  *    they must take a pointer to a IDirect3D structure and we must cast it to an _IDirect3D so that 
     299 *  - Then we implement the interface methods. To match what has been declared in the header file
     300 *    they must take a pointer to a IDirect3D structure and we must cast it to an _IDirect3D so that
    301301 *    we can manipulate the fields. This is performed by the ICOM_THIS macro.
    302302 *  - Finally we initialize the virtual table.
     
    315315
    316316#ifndef ICOM_VIRTUAL_METHODS
    317 /* Uses these macros, i.e. do not define ICOM_VIRTUAL_METHODS, if your C++ compiler does not generate 
     317/* Uses these macros, i.e. do not define ICOM_VIRTUAL_METHODS, if your C++ compiler does not generate
    318318 * virtual tables with the right layout (i.e. currently most g++ derivatives).
    319319 */
     
    481481
    482482#else
    483 /* This case can be used if the layout of the virtual tables generated by the C++ 
     483/* This case can be used if the layout of the virtual tables generated by the C++
    484484 * compiler matches that of Visual C++.
    485485 */
     
    775775 * Predeclare the interfaces
    776776 */
    777 DEFINE_OLEGUID(IID_IClassFactory,       0x00000001L, 0, 0);
     777DEFINE_OLEGUID(IID_IClassFactory,        0x00000001L, 0, 0);
    778778typedef struct IClassFactory IClassFactory, *LPCLASSFACTORY;
    779779
    780 DEFINE_OLEGUID(IID_IMalloc,             0x00000002L, 0, 0);
     780DEFINE_OLEGUID(IID_IMalloc,                 0x00000002L, 0, 0);
    781781typedef struct IMalloc16 IMalloc16,*LPMALLOC16;
    782782typedef struct IMalloc IMalloc,*LPMALLOC;
    783783
    784 DEFINE_OLEGUID(IID_IUnknown,            0x00000000L, 0, 0);
     784DEFINE_OLEGUID(IID_IUnknown,                0x00000000L, 0, 0);
    785785typedef struct IUnknown IUnknown, *LPUNKNOWN;
    786786
     
    992992
    993993HRESULT WINAPI CoRevokeClassObject(DWORD dwRegister);
     994HRESULT WINAPI CoRegisterSurrogate(LPSURROGATE pSurrogate);
    994995
    995996/*****************************************************************************
    996  *      COM Server dll - exports
     997 * COM Server dll - exports
    997998 */
    998999HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID * ppv);
Note: See TracChangeset for help on using the changeset viewer.