Ignore:
Timestamp:
Aug 23, 1999, 12:52:05 AM (26 years ago)
Author:
sandervl
Message:

Updated Wine headers

File:
1 edited

Legend:

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

    r261 r640  
    1 /* $Id: obj_base.h,v 1.6 1999-07-04 09:35:04 sandervl Exp $ */
    21/*
    3  * This file defines the macros and types necessary to define COM interfaces,
     2 * This file defines the macros and types necessary to define COM interfaces, 
    43 * and the three most basic COM interfaces: IUnknown, IMalloc and IClassFactory.
    54 */
     
    87#define __WINE_WINE_OBJ_BASE_H
    98
     9/*****************************************************************************
     10 * define ICOM_MSVTABLE_COMPAT
     11 * to implement the microsoft com vtable compatibility workaround for g++.
     12 *
     13 * NOTE: Turning this option on will produce a winelib that is incompatible
     14 * with the binary emulator.
     15 *
     16 * If the compiler supports the com_interface attribute, leave this off, and
     17 * define the ICOM_USE_COM_INTERFACE_ATTRIBUTE macro below.
     18 *
     19 * If you aren't interested in WineLib C++ compatability at all, leave both
     20 * options off.
     21 */
     22/* #define ICOM_MSVTABLE_COMPAT 1 */
     23/* #define ICOM_USE_COM_INTERFACE_ATTRIBUTE 1 */
    1024
    1125/*****************************************************************************
     
    1428#include "wtypes.h"
    1529
     30
     31#define LISet32(li, v)   ((li).HighPart = (v) < 0 ? -1 : 0, (li).LowPart = (v))
     32#define ULISet32(li, v)  ((li).HighPart = 0, (li).LowPart = (v))
    1633
    1734/*****************************************************************************
     
    2138#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
    2239        extern const GUID name = \
    23    { l, w1, w2, { b1, b2,  b3,  b4,  b5,  b6,  b7,  b8 } }
     40        { l, w1, w2, { b1, b2,  b3,  b4,  b5,  b6,  b7,  b8 } }
    2441#else
    2542#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
     
    2845
    2946#define DEFINE_OLEGUID(name, l, w1, w2) \
    30    DEFINE_GUID(name, l, w1, w2, 0xC0,0,0,0,0,0,0,0x46)
     47        DEFINE_GUID(name, l, w1, w2, 0xC0,0,0,0,0,0,0,0x46)
    3148
    3249#define DEFINE_SHLGUID(name, l, w1, w2) DEFINE_OLEGUID(name,l,w1,w2)
     
    5067BOOL WINAPI IsEqualGUID32(REFGUID rguid1,REFGUID rguid2);
    5168/*#define IsEqualGUID WINELIB_NAME(IsEqualGUID)*/
    52 #ifdef __cplusplus
     69#if defined(__cplusplus) && !defined(CINTERFACE)
    5370#define IsEqualGUID(rguid1, rguid2) (!memcmp(&(rguid1), &(rguid2), sizeof(GUID)))
    54 #else
     71#else /* defined(__cplusplus) && !defined(CINTERFACE) */
    5572#define IsEqualGUID(rguid1, rguid2) (!memcmp(rguid1, rguid2, sizeof(GUID)))
    56 #endif /* cplusplus */
     73#endif /* defined(__cplusplus) && !defined(CINTERFACE) */
    5774#define IsEqualIID(riid1, riid2) IsEqualGUID(riid1, riid2)
    5875#define IsEqualCLSID(rclsid1, rclsid2) IsEqualGUID(rclsid1, rclsid2)
    5976
    60 #ifdef __cplusplus
     77#if defined(__cplusplus) && !defined(CINTERFACE)
    6178inline BOOL operator==(const GUID& guidOne, const GUID& guidOther)
    6279{
     
    6784    return !(guidOne == guidOther);
    6885}
    69 #endif
     86#endif 
    7087
    7188
     
    7491 */
    7592/*
    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++
     93 * The goal of the following set of definitions is to provide a way to use the same 
     94 * header file definitions to provide both a C interface and a C++ object oriented 
     95 * interface to COM interfaces. The type of interface is selected automatically 
     96 * depending on the language but it is always possible to get the C interface in C++ 
    8097 * by defining CINTERFACE.
    8198 *
    8299 * It is based on the following assumptions:
    83100 *  - 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
     101 *  - the header file only defines the interface, the actual fields are defined 
    85102 *    separately in the C file implementing the interface.
    86103 *
    87  * The natural approach to this problem would be to make sure we get a C++ class and
     104 * The natural approach to this problem would be to make sure we get a C++ class and 
    88105 * 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
     106 * Unfortunately the layout of the virtual table is compiler specific, the layout of 
     107 * g++ virtual tables is not the same as that of an egcs virtual table which is not the 
     108 * same as that generated by Visual C+. There are workarounds to make the virtual tables 
    92109 * compatible via padding but unfortunately the one which is imposed to the WINE emulator
    93110 * by the Windows binaries, i.e. the Visual C++ one, is the most compact of all.
    94111 *
    95  * So the solution I finally adopted does not use virtual tables. Instead I use inline
     112 * So the solution I finally adopted does not use virtual tables. Instead I use inline 
    96113 * non virtual methods that dereference the method pointer themselves and perform the call.
    97114 *
     
    127144 *
    128145 * 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
     146 *  - The ICOM_INTERFACE macro is used in the ICOM_METHOD macros to define the type of the 'this' 
     147 *    pointer. Defining this macro here saves us the trouble of having to repeat the interface 
     148 *    name everywhere. Note however that because of the way macros work, a macro like ICOM_METHOD1 
     149 *    cannot use 'ICOM_INTERFACE##_VTABLE' because this would give 'ICOM_INTERFACE_VTABLE' and not 
    133150 *    'IDirect3D_VTABLE'.
    134  *  - ICOM_METHODS defines the methods specific to this interface. It is then aggregated with the
     151 *  - ICOM_METHODS defines the methods specific to this interface. It is then aggregated with the 
    135152 *    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
     153 *  - ICOM_IMETHODS defines the list of methods that are inheritable from this interface. It must 
     154 *    be written manually (rather than using a macro to generate the equivalent code) to avoid 
    138155 *    macro recursion (which compilers don't like).
    139  *  - The ICOM_DEFINE finally declares all the structures necessary for the interface. We have to
     156 *  - The ICOM_DEFINE finally declares all the structures necessary for the interface. We have to 
    140157 *    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
     158 *    Inherited methods are inherited in C by using the IDirect3D_METHODS macro and the parent's 
     159 *    Xxx_IMETHODS macro. In C++ we need only use the IDirect3D_METHODS since method inheritance 
    143160 *    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
     161 *  - In C++ the ICOM_METHOD macros generate a function prototype and a call to a function pointer 
     162 *    method. This means using once 't1 p1, t2 p2, ...' and once 'p1, p2' without the types. The 
     163 *    only way I found to handle this is to have one ICOM_METHOD macro per number of parameters and 
    147164 *    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
     165 *    The 'undef ICOM_INTERFACE' is here to remind you that using ICOM_INTERFACE in the following 
     166 *    macros will not work. This time it's because the ICOM_CALL macro expansion is done only once 
     167 *    the 'IDirect3D_Xxx' macro is expanded. And by that time ICOM_INTERFACE will be long gone 
    151168 *    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),
     169 *  - You may have noticed the double commas after each parameter type. This allows you to put the 
     170 *    name of that parameter which I think is good for documentation. It is not required and since 
     171 *    I did not know what to put there for this example (I could only find doc about IDirect3D2), 
    155172 *    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
     173 *  - Finally the set of 'IDirect3D_Xxx' macros is a standard set of macros defined to ease access 
     174 *    to the interface methods in C. Unfortunately I don't see any way to avoid having to duplicate 
     175 *    the inherited method definitions there. This time I could have used a trick to use only one 
    159176 *    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
     177 *  - You probably have noticed that we don't define the fields we need to actually implement this 
     178 *    interface: reference count, pointer to other resources and miscellaneous fields. That's 
     179 *    because these interfaces are just that: interfaces. They may be implemented more than once, in 
     180 *    different contexts and sometimes not even in Wine. Thus it would not make sense to impose 
    164181 *    that the interface contains some specific fields.
    165182 *
     
    180197 *        HRESULT (*fnCreateViewport)(IDirect3D* me, LPDIRECT3DVIEWPORT* a, IUnknown* b);
    181198 *        HRESULT (*fnFindDevice)(IDirect3D* me, LPD3DFINDDEVICESEARCH a, LPD3DFINDDEVICERESULT b);
    182  *    };
     199 *    }; 
    183200 *
    184201 *    #ifdef ICOM_CINTERFACE
     
    197214 *
    198215 * 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
     216 *  - IDirect3D only contains a pointer to the IDirect3D virtual/jump table. This is the only thing 
     217 *    the user needs to know to use the interface. Of course the structure we will define to 
    201218 *    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
     219 *  - The code generated by ICOM_DEFINE defines both the structure representing the interface and 
     220 *    the structure for the jump table. ICOM_DEFINE uses the parent's Xxx_IMETHODS macro to 
     221 *    automatically repeat the prototypes of all the inherited methods and then uses IDirect3D_METHODS 
    205222 *    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
     223 *  - Each method is declared as a pointer to function field in the jump table. The implementation 
     224 *    will fill this jump table with appropriate values, probably using a static variable, and 
    208225 *    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
     226 *  - The IDirect3D_Xxx macros then just derefence the lpvtbl pointer and use the function pointer 
     227 *    corresponding to the macro name. This emulates the behavior of a virtual table and should be 
    211228 *    just as fast.
    212  *  - This C code should be quite compatible with the Windows headers both for code that uses COM
     229 *  - This C code should be quite compatible with the Windows headers both for code that uses COM 
    213230 *    interfaces and for code implementing a COM interface.
    214231 *
     
    234251 *        public: inline HRESULT FindDevice(LPD3DFINDDEVICESEARCH a, LPD3DFINDDEVICERESULT b)
    235252 *            { return ((IDirect3D*)t.lpvtbl)->fnFindDevice(this,a,b); };
    236  *    };
     253 *    }; 
    237254 *
    238255 * 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
     256 *  - In C++ IDirect3D does double duty as both the virtual/jump table and as the interface 
     257 *    definition. The reason for this is to avoid having to duplicate the mehod definitions: once 
     258 *    to have the function pointers in the jump table and once to have the methods in the interface 
     259 *    class. Here one macro can generate both. This means though that the first pointer, t.lpvtbl 
     260 *    defined in IUnknown,  must be interpreted as the jump table pointer if we interpret the 
     261 *    structure as the the interface class, and as the function pointer to the QueryInterface 
     262 *    method, t.fnQueryInterface, if we interpret the structure as the jump table. Fortunately this 
    246263 *    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
     264 *  - Of course in C++ we use inheritance so that we don't have to duplicate the method definitions. 
     265 *  - Since IDirect3D does double duty, each ICOM_METHOD macro defines both a function pointer and 
     266 *    a non-vritual inline method which dereferences it and calls it. This way this method behaves 
     267 *    just like a virtual method but does not create a true C++ virtual table which would break the 
     268 *    structure layout. If you look at the implementation of these methods you'll notice that they 
     269 *    would not work for void functions. We have to return something and fortunately this seems to 
    253270 *    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
     271 *  - Note how the ICOM_METHOD generates both function prototypes mixing types and formal parameter 
     272 *    names and the method invocation using only the formal parameter name. This is the reason why 
    256273 *    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
     274 *  - Finally there is no IDirect3D_Xxx macro. These are not needed in C++ unless the CINTERFACE 
    258275 *    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
     276 *  - This C++ code works well for code that just uses COM interfaces. But it will not work with 
     277 *    C++ code implement a COM interface. That's because such code assumes the interface methods 
    261278 *    are declared as virtual C++ methods which is not the case here.
    262279 *
     
    293310 *
    294311 * Comments:
    295  *  - We first define what the interface really contains. This is th e_IDirect3D structure. The
     312 *  - We first define what the interface really contains. This is th e_IDirect3D structure. The 
    296313 *    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
     314 *  - Then we predeclare our static virtual table variable, we will need its address in some 
    298315 *    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
     316 *  - Then we implement the interface methods. To match what has been declared in the header file 
     317 *    they must take a pointer to a IDirect3D structure and we must cast it to an _IDirect3D so that 
    301318 *    we can manipulate the fields. This is performed by the ICOM_THIS macro.
    302319 *  - Finally we initialize the virtual table.
     
    314331/* C++ interface */
    315332
    316 #ifndef ICOM_VIRTUAL_METHODS
    317 /* Uses these macros, i.e. do not define ICOM_VIRTUAL_METHODS, if your C++ compiler does not generate
    318  * virtual tables with the right layout (i.e. currently most g++ derivatives).
    319  */
    320 
    321333#define ICOM_METHOD(ret,xfn) \
    322     private: ret (CALLBACK *fn##xfn)(ICOM_INTERFACE* me); \
    323     public: inline ret (CALLBACK xfn)(void) { return ((ICOM_INTERFACE*)t.lpvtbl)->fn##xfn(this); };
     334     public: virtual ret (CALLBACK xfn)(void) = 0;
    324335
    325336#define ICOM_METHOD1(ret,xfn,ta,na) \
    326     private: ret (CALLBACK *fn##xfn)(ICOM_INTERFACE* me,ta a); \
    327     public: inline ret (CALLBACK xfn)(ta a) { return ((ICOM_INTERFACE*)t.lpvtbl)->fn##xfn(this,a); };
     337     public: virtual ret (CALLBACK xfn)(ta a) = 0;
    328338
    329339#define ICOM_METHOD2(ret,xfn,ta,na,tb,nb) \
    330     private: ret (CALLBACK *fn##xfn)(ICOM_INTERFACE* me,ta a,tb b); \
    331     public: inline ret (CALLBACK xfn)(ta a,tb b) { return ((ICOM_INTERFACE*)t.lpvtbl)->fn##xfn(this,a,b); };
     340     public: virtual ret (CALLBACK xfn)(ta a,tb b) = 0;
    332341
    333342#define ICOM_METHOD3(ret,xfn,ta,na,tb,nb,tc,nc) \
    334     private: ret (CALLBACK *fn##xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c); \
    335     public: inline ret (CALLBACK xfn)(ta a,tb b,tc c) { return ((ICOM_INTERFACE*)t.lpvtbl)->fn##xfn(this,a,b,c); };
     343     public: virtual ret (CALLBACK xfn)(ta a,tb b,tc c) = 0;
    336344
    337345#define ICOM_METHOD4(ret,xfn,ta,na,tb,nb,tc,nc,td,nd) \
    338     private: ret (CALLBACK *fn##xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d); \
    339     public: inline ret (CALLBACK xfn)(ta a,tb b,tc c,td d) { return ((ICOM_INTERFACE*)t.lpvtbl)->fn##xfn(this,a,b,c,d); };
     346     public: virtual ret (CALLBACK xfn)(ta a,tb b,tc c,td d) = 0;
    340347
    341348#define ICOM_METHOD5(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne) \
    342     private: ret (CALLBACK *fn##xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e); \
    343     public: inline ret (CALLBACK xfn)(ta a,tb b,tc c,td d,te e) { return ((ICOM_INTERFACE*)t.lpvtbl)->fn##xfn(this,a,b,c,d,e); };
     349     public: virtual ret (CALLBACK xfn)(ta a,tb b,tc c,td d,te e) = 0;
    344350
    345351#define ICOM_METHOD6(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf) \
    346     private: ret (CALLBACK *fn##xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f); \
    347     public: inline ret (CALLBACK xfn)(ta a,tb b,tc c,td d,te e,tf f) { return ((ICOM_INTERFACE*)t.lpvtbl)->fn##xfn(this,a,b,c,d,e,f); };
     352     public: virtual ret (CALLBACK xfn)(ta a,tb b,tc c,td d,te e,tf f) = 0;
    348353
    349354#define ICOM_METHOD7(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng) \
    350     private: ret (CALLBACK *fn##xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g); \
    351     public: inline ret (CALLBACK xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g) { return ((ICOM_INTERFACE*)t.lpvtbl)->fn##xfn(this,a,b,c,d,e,f,g); };
     355     public: virtual ret (CALLBACK xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g) = 0;
    352356
    353357#define ICOM_METHOD8(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh) \
    354     private: ret (CALLBACK *fn##xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h); \
    355     public: inline ret (CALLBACK xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g,th h) { return ((ICOM_INTERFACE*)t.lpvtbl)->fn##xfn(this,a,b,c,d,e,f,g,h); };
     358     public: virtual ret (CALLBACK xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g,th h) = 0;
    356359
    357360#define ICOM_METHOD9(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni) \
    358     private: ret (CALLBACK *fn##xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i); \
    359     public: inline ret (CALLBACK xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i) { return ((ICOM_INTERFACE*)t.lpvtbl)->fn##xfn(this,a,b,c,d,e,f,g,h,i); };
     361     public: virtual ret (CALLBACK xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i) = 0;
    360362
    361363#define ICOM_METHOD10(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni,tj,nj) \
    362     private: ret (CALLBACK *fn##xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i,tj j); \
    363     public: inline ret (CALLBACK xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i,tj j) { return ((ICOM_INTERFACE*)t.lpvtbl)->fn##xfn(this,a,b,c,d,e,f,g,h,i,j); };
     364     public: virtual ret (CALLBACK xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i,tj j) = 0;
    364365
    365366
    366367#define ICOM_CMETHOD(ret,xfn) \
    367     private: ret (CALLBACK *fn##xfn)(const ICOM_INTERFACE* me); \
    368     public: inline ret (CALLBACK xfn)(void) const { return ((ICOM_INTERFACE*)t.lpvtbl)->fn##xfn(this); };
     368     public: virtual ret (CALLBACK xfn)(void) const = 0;
    369369
    370370#define ICOM_CMETHOD1(ret,xfn,ta,na) \
    371     private: ret (CALLBACK *fn##xfn)(const ICOM_INTERFACE* me,ta a); \
    372     public: inline ret (CALLBACK xfn)(ta a) const { return ((ICOM_INTERFACE*)t.lpvtbl)->fn##xfn(this,a); };
     371     public: virtual ret (CALLBACK xfn)(ta a) const = 0;
    373372
    374373#define ICOM_CMETHOD2(ret,xfn,ta,na,tb,nb) \
    375     private: ret (CALLBACK *fn##xfn)(const ICOM_INTERFACE* me,ta a,tb b); \
    376     public: inline ret (CALLBACK xfn)(ta a,tb b) const { return ((ICOM_INTERFACE*)t.lpvtbl)->fn##xfn(this,a,b); };
     374     public: virtual ret (CALLBACK xfn)(ta a,tb b) const = 0;
    377375
    378376#define ICOM_CMETHOD3(ret,xfn,ta,na,tb,nb,tc,nc) \
    379     private: ret (CALLBACK *fn##xfn)(const ICOM_INTERFACE* me,ta a,tb b,tc c); \
    380     public: inline ret (CALLBACK xfn)(ta a,tb b,tc c) const { return ((ICOM_INTERFACE*)t.lpvtbl)->fn##xfn(this,a,b,c); };
     377     public: virtual ret (CALLBACK xfn)(ta a,tb b,tc c) const = 0;
    381378
    382379#define ICOM_CMETHOD4(ret,xfn,ta,na,tb,nb,tc,nc,td,nd) \
    383     private: ret (CALLBACK *fn##xfn)(const ICOM_INTERFACE* me,ta a,tb b,tc c,td d); \
    384     public: inline ret (CALLBACK xfn)(ta a,tb b,tc c,td d) const { return ((ICOM_INTERFACE*)t.lpvtbl)->fn##xfn(this,a,b,c,d); };
     380     public: virtual ret (CALLBACK xfn)(ta a,tb b,tc c,td d) const = 0;
    385381
    386382#define ICOM_CMETHOD5(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne) \
    387     private: ret (CALLBACK *fn##xfn)(const ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e); \
    388     public: inline ret (CALLBACK xfn)(ta a,tb b,tc c,td d,te e) const { return ((ICOM_INTERFACE*)t.lpvtbl)->fn##xfn(this,a,b,c,d,e); };
     383     public: virtual ret (CALLBACK xfn)(ta a,tb b,tc c,td d,te e) const = 0;
    389384
    390385#define ICOM_CMETHOD6(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf) \
    391     private: ret (CALLBACK *fn##xfn)(const ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f); \
    392     public: inline ret (CALLBACK xfn)(ta a,tb b,tc c,td d,te e,tf f) const { return ((ICOM_INTERFACE*)t.lpvtbl)->fn##xfn(this,a,b,c,d,e,f); };
     386     public: virtual ret (CALLBACK xfn)(ta a,tb b,tc c,td d,te e,tf f) const = 0;
    393387
    394388#define ICOM_CMETHOD7(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng) \
    395     private: ret (CALLBACK *fn##xfn)(const ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g); \
    396     public: inline ret (CALLBACK xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g) const { return ((ICOM_INTERFACE*)t.lpvtbl)->fn##xfn(this,a,b,c,d,e,f,g); };
     389     public: virtual ret (CALLBACK xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g) const = 0;
    397390
    398391#define ICOM_CMETHOD8(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh) \
    399     private: ret (CALLBACK *fn##xfn)(const ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h); \
    400     public: inline ret (CALLBACK xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g,th h) const { return ((ICOM_INTERFACE*)t.lpvtbl)->fn##xfn(this,a,b,c,d,e,f,g,h); };
     392     public: virtual ret (CALLBACK xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g,th h) const = 0;
    401393
    402394
    403395#define ICOM_VMETHOD(xfn) \
    404     private: void (CALLBACK *fn##xfn)(ICOM_INTERFACE* me); \
    405     public: inline void (CALLBACK xfn)(void) { ((ICOM_INTERFACE*)t.lpvtbl)->fn##xfn(this); };
     396     public: virtual void (CALLBACK xfn)(void) = 0;
    406397
    407398#define ICOM_VMETHOD1(xfn,ta,na) \
    408     private: void (CALLBACK *fn##xfn)(ICOM_INTERFACE* me,ta a); \
    409     public: inline void (CALLBACK xfn)(ta a) { ((ICOM_INTERFACE*)t.lpvtbl)->fn##xfn(this,a); };
     399     public: virtual void (CALLBACK xfn)(ta a) = 0;
    410400
    411401#define ICOM_VMETHOD2(xfn,ta,na,tb,nb) \
    412     private: void (CALLBACK *fn##xfn)(ICOM_INTERFACE* me,ta a,tb b); \
    413     public: inline void (CALLBACK xfn)(ta a,tb b) { ((ICOM_INTERFACE*)t.lpvtbl)->fn##xfn(this,a,b); };
     402     public: virtual void (CALLBACK xfn)(ta a,tb b) = 0;
    414403
    415404#define ICOM_VMETHOD3(xfn,ta,na,tb,nb,tc,nc) \
    416     private: void (CALLBACK *fn##xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c); \
    417     public: inline void (CALLBACK xfn)(ta a,tb b,tc c) { ((ICOM_INTERFACE*)t.lpvtbl)->fn##xfn(this,a,b,c); };
     405     public: virtual void (CALLBACK xfn)(ta a,tb b,tc c) = 0;
    418406
    419407#define ICOM_VMETHOD4(xfn,ta,na,tb,nb,tc,nc,td,nd) \
    420     private: void (CALLBACK *fn##xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d); \
    421     public: inline void (CALLBACK xfn)(ta a,tb b,tc c,td d) { ((ICOM_INTERFACE*)t.lpvtbl)->fn##xfn(this,a,b,c,d); };
     408     public: virtual void (CALLBACK xfn)(ta a,tb b,tc c,td d) = 0;
    422409
    423410#define ICOM_VMETHOD5(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne) \
    424     private: void (CALLBACK *fn##xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e); \
    425     public: inline void (CALLBACK xfn)(ta a,tb b,tc c,td d,te e) { ((ICOM_INTERFACE*)t.lpvtbl)->fn##xfn(this,a,b,c,d,e); };
     411     public: virtual void (CALLBACK xfn)(ta a,tb b,tc c,td d,te e) = 0;
    426412
    427413#define ICOM_VMETHOD6(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf) \
    428     private: void (CALLBACK *fn##xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f); \
    429     public: inline void (CALLBACK xfn)(ta a,tb b,tc c,td d,te e,tf f) { ((ICOM_INTERFACE*)t.lpvtbl)->fn##xfn(this,a,b,c,d,e,f); };
     414     public: virtual void (CALLBACK xfn)(ta a,tb b,tc c,td d,te e,tf f) = 0;
    430415
    431416#define ICOM_VMETHOD7(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng) \
    432     private: void (CALLBACK *fn##xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g); \
    433     public: inline void (CALLBACK xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g) { ((ICOM_INTERFACE*)t.lpvtbl)->fn##xfn(this,a,b,c,d,e,f,g); };
     417     public: virtual void (CALLBACK xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g) = 0;
    434418
    435419#define ICOM_VMETHOD8(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh) \
    436     private: void (CALLBACK *fn##xfn)(ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h); \
    437     public: inline void (CALLBACK xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g,th h) { ((ICOM_INTERFACE*)t.lpvtbl)->fn##xfn(this,a,b,c,d,e,f,g,h); };
     420     public: virtual void (CALLBACK xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g,th h) = 0;
    438421
    439422
    440423#define ICOM_CVMETHOD(xfn) \
    441     private: void (CALLBACK *fn##xfn)(const ICOM_INTERFACE* me); \
    442     public: inline void (CALLBACK xfn)(void) const { ((ICOM_INTERFACE*)t.lpvtbl)->fn##xfn(this); };
     424     public: virtual void (CALLBACK xfn)(void) const = 0;
    443425
    444426#define ICOM_CVMETHOD1(xfn,ta,na) \
    445     private: void (CALLBACK *fn##xfn)(const ICOM_INTERFACE* me,ta a); \
    446     public: inline void (CALLBACK xfn)(ta a) const { ((ICOM_INTERFACE*)t.lpvtbl)->fn##xfn(this,a); };
     427     public: virtual void (CALLBACK xfn)(ta a) const = 0;
    447428
    448429#define ICOM_CVMETHOD2(xfn,ta,na,tb,nb) \
    449     private: void (CALLBACK *fn##xfn)(const ICOM_INTERFACE* me,ta a,tb b); \
    450     public: inline void (CALLBACK xfn)(ta a,tb b) const { ((ICOM_INTERFACE*)t.lpvtbl)->fn##xfn(this,a,b); };
     430     public: virtual void (CALLBACK xfn)(ta a,tb b) const = 0;
    451431
    452432#define ICOM_CVMETHOD3(xfn,ta,na,tb,nb,tc,nc) \
    453     private: void (CALLBACK *fn##xfn)(const ICOM_INTERFACE* me,ta a,tb b,tc c); \
    454     public: inline void (CALLBACK xfn)(ta a,tb b,tc c) const { ((ICOM_INTERFACE*)t.lpvtbl)->fn##xfn(this,a,b,c); };
     433     public: virtual void (CALLBACK xfn)(ta a,tb b,tc c) const = 0;
    455434
    456435#define ICOM_CVMETHOD4(xfn,ta,na,tb,nb,tc,nc,td,nd) \
    457     private: void (CALLBACK *fn##xfn)(const ICOM_INTERFACE* me,ta a,tb b,tc c,td d); \
    458     public: inline void (CALLBACK xfn)(ta a,tb b,tc c,td d) const { ((ICOM_INTERFACE*)t.lpvtbl)->fn##xfn(this,a,b,c,d); };
     436     public: virtual void (CALLBACK xfn)(ta a,tb b,tc c,td d) const = 0;
    459437
    460438#define ICOM_CVMETHOD5(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne) \
    461     private: void (CALLBACK *fn##xfn)(const ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e); \
    462     public: inline void (CALLBACK xfn)(ta a,tb b,tc c,td d,te e) const { ((ICOM_INTERFACE*)t.lpvtbl)->fn##xfn(this,a,b,c,d,e); };
     439     public: virtual void (CALLBACK xfn)(ta a,tb b,tc c,td d,te e) const = 0;
    463440
    464441#define ICOM_CVMETHOD6(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf) \
    465     private: void (CALLBACK *fn##xfn)(const ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f); \
    466     public: inline void (CALLBACK xfn)(ta a,tb b,tc c,td d,te e,tf f) const { ((ICOM_INTERFACE*)t.lpvtbl)->fn##xfn(this,a,b,c,d,e,f); };
     442     public: virtual void (CALLBACK xfn)(ta a,tb b,tc c,td d,te e,tf f) const = 0;
    467443
    468444#define ICOM_CVMETHOD7(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng) \
    469     private: void (CALLBACK *fn##xfn)(const ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g); \
    470     public: inline void (CALLBACK xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g) const { ((ICOM_INTERFACE*)t.lpvtbl)->fn##xfn(this,a,b,c,d,e,f,g); };
     445     public: virtual void (CALLBACK xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g) const = 0;
    471446
    472447#define ICOM_CVMETHOD8(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh) \
    473     private: void (CALLBACK *fn##xfn)(const ICOM_INTERFACE* me,ta a,tb b,tc c,td d,te e,tf f,tg g,th h); \
    474     public: inline void (CALLBACK xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g,th h) const { ((ICOM_INTERFACE*)t.lpvtbl)->fn##xfn(this,a,b,c,d,e,f,g,h); };
    475 
     448     public: virtual void (CALLBACK xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g,th h) const = 0;
     449
     450#ifdef ICOM_USE_COM_INTERFACE_ATTRIBUTE
     451
     452#define ICOM_DEFINE(iface,ibase) \
     453    typedef struct iface: public ibase { \
     454        iface##_METHODS \
     455            } __attribute__ ((com_interface));
     456
     457#else
    476458
    477459#define ICOM_DEFINE(iface,ibase) \
     
    480462    };
    481463
    482 #else
    483 /* This case can be used if the layout of the virtual tables generated by the C++
    484  * compiler matches that of Visual C++.
    485  */
    486 
    487 #define ICOM_METHOD(ret,xfn) \
    488     virtual ret (CALLBACK xfn)(void) = 0;
    489 
    490 #define ICOM_METHOD1(ret,xfn,ta,na) \
    491     virtual ret (CALLBACK xfn)(ta a) = 0;
    492 
    493 #define ICOM_METHOD2(ret,xfn,ta,na,tb,nb) \
    494     virtual ret (CALLBACK xfn)(ta a,tb b) = 0;
    495 
    496 #define ICOM_METHOD3(ret,xfn,ta,na,tb,nb,tc,nc) \
    497     virtual ret (CALLBACK xfn)(ta a,tb b,tc c) = 0;
    498 
    499 #define ICOM_METHOD4(ret,xfn,ta,na,tb,nb,tc,nc,td,nd) \
    500     virtual ret (CALLBACK xfn)(ta a,tb b,tc c,td d) = 0;
    501 
    502 #define ICOM_METHOD5(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne) \
    503     virtual ret (CALLBACK xfn)(ta a,tb b,tc c,td d,te e) = 0;
    504 
    505 #define ICOM_METHOD6(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf) \
    506     virtual ret (CALLBACK xfn)(ta a,tb b,tc c,td d,te e,tf f) = 0;
    507 
    508 #define ICOM_METHOD7(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng) \
    509     virtual ret (CALLBACK xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g) = 0;
    510 
    511 #define ICOM_METHOD8(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh) \
    512     virtual ret (CALLBACK xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g,th h) = 0;
    513 
    514 #define ICOM_METHOD9(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni) \
    515     virtual ret (CALLBACK xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i) = 0;
    516 
    517 #define ICOM_METHOD10(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh,ti,ni,tj,nj) \
    518     virtual ret (CALLBACK xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g,th h,ti i,tj j) = 0;
    519 
    520 
    521 #define ICOM_CMETHOD(ret,xfn) \
    522     virtual ret (CALLBACK xfn)(void) const = 0;
    523 
    524 #define ICOM_CMETHOD1(ret,xfn,ta,na) \
    525     virtual ret (CALLBACK xfn)(ta a) const = 0;
    526 
    527 #define ICOM_CMETHOD2(ret,xfn,ta,na,tb,nb) \
    528     virtual ret (CALLBACK xfn)(ta a,tb b) const = 0;
    529 
    530 #define ICOM_CMETHOD3(ret,xfn,ta,na,tb,nb,tc,nc) \
    531     virtual ret (CALLBACK xfn)(ta a,tb b,tc c) const = 0;
    532 
    533 #define ICOM_CMETHOD4(ret,xfn,ta,na,tb,nb,tc,nc,td,nd) \
    534     virtual ret (CALLBACK xfn)(ta a,tb b,tc c,td d) const = 0;
    535 
    536 #define ICOM_CMETHOD5(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne) \
    537     virtual ret (CALLBACK xfn)(ta a,tb b,tc c,td d,te e) const = 0;
    538 
    539 #define ICOM_CMETHOD6(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf) \
    540     virtual ret (CALLBACK xfn)(ta a,tb b,tc c,td d,te e,tf f) const = 0;
    541 
    542 #define ICOM_CMETHOD7(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng) \
    543     virtual ret (CALLBACK xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g) const = 0;
    544 
    545 #define ICOM_CMETHOD8(ret,xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh) \
    546     virtual ret (CALLBACK xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g,th h) const = 0;
    547 
    548 
    549 #define ICOM_VMETHOD(xfn) \
    550     virtual void (CALLBACK xfn)(void) = 0;
    551 
    552 #define ICOM_VMETHOD1(xfn,ta,na) \
    553     virtual void (CALLBACK xfn)(ta a) = 0;
    554 
    555 #define ICOM_VMETHOD2(xfn,ta,na,tb,nb) \
    556     virtual void (CALLBACK xfn)(ta a,tb b) = 0;
    557 
    558 #define ICOM_VMETHOD3(xfn,ta,na,tb,nb,tc,nc) \
    559     virtual void (CALLBACK xfn)(ta a,tb b,tc c) = 0;
    560 
    561 #define ICOM_VMETHOD4(xfn,ta,na,tb,nb,tc,nc,td,nd) \
    562     virtual void (CALLBACK xfn)(ta a,tb b,tc c,td d) = 0;
    563 
    564 #define ICOM_VMETHOD5(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne) \
    565     virtual void (CALLBACK xfn)(ta a,tb b,tc c,td d,te e) = 0;
    566 
    567 #define ICOM_VMETHOD6(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf) \
    568     virtual void (CALLBACK xfn)(ta a,tb b,tc c,td d,te e,tf f) = 0;
    569 
    570 #define ICOM_VMETHOD7(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng) \
    571     virtual void (CALLBACK xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g) = 0;
    572 
    573 #define ICOM_VMETHOD8(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh) \
    574     virtual void (CALLBACK xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g,th h) = 0;
    575 
    576 
    577 #define ICOM_CVMETHOD(xfn) \
    578     virtual void (CALLBACK xfn)(void) const = 0;
    579 
    580 #define ICOM_CVMETHOD1(xfn,ta,na) \
    581     virtual void (CALLBACK xfn)(ta a) const = 0;
    582 
    583 #define ICOM_CVMETHOD2(xfn,ta,na,tb,nb) \
    584     virtual void (CALLBACK xfn)(ta a,tb b) const = 0;
    585 
    586 #define ICOM_CVMETHOD3(xfn,ta,na,tb,nb,tc,nc) \
    587     virtual void (CALLBACK xfn)(ta a,tb b,tc c) const = 0;
    588 
    589 #define ICOM_CVMETHOD4(xfn,ta,na,tb,nb,tc,nc,td,nd) \
    590     virtual void (CALLBACK xfn)(ta a,tb b,tc c,td d) const = 0;
    591 
    592 #define ICOM_CVMETHOD5(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne) \
    593     virtual void (CALLBACK xfn)(ta a,tb b,tc c,td d,te e) const = 0;
    594 
    595 #define ICOM_CVMETHOD6(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf) \
    596     virtual void (CALLBACK xfn)(ta a,tb b,tc c,td d,te e,tf f) const = 0;
    597 
    598 #define ICOM_CVMETHOD7(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng) \
    599     virtual void (CALLBACK xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g) const = 0;
    600 
    601 #define ICOM_CVMETHOD8(xfn,ta,na,tb,nb,tc,nc,td,nd,te,ne,tf,nf,tg,ng,th,nh) \
    602     virtual void (CALLBACK xfn)(ta a,tb b,tc c,td d,te e,tf f,tg g,th h) const = 0;
    603 
    604 #endif
    605 
    606 
    607 #define ICOM_DEFINE(iface,ibase) \
    608     typedef struct iface: public ibase { \
    609         iface##_METHODS \
    610     };
     464#endif /* ICOM_USE_COM_INTERFACE_ATTRIBUTE */
    611465
    612466#define ICOM_CALL(xfn, p)                        this_is_a_syntax_error
     
    743597
    744598
     599#ifdef ICOM_MSVTABLE_COMPAT
     600#define ICOM_DEFINE(iface,ibase) \
     601    typedef struct ICOM_VTABLE(iface) ICOM_VTABLE(iface); \
     602    struct iface { \
     603        const ICOM_VTABLE(iface)* lpvtbl; \
     604    }; \
     605    struct ICOM_VTABLE(iface) { \
     606        long dummyRTTI1; \
     607        long dummyRTTI2; \
     608        ibase##_IMETHODS \
     609        iface##_METHODS \
     610    };
     611#define ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE 0,0,
     612
     613#else
    745614#define ICOM_DEFINE(iface,ibase) \
    746615    typedef struct ICOM_VTABLE(iface) ICOM_VTABLE(iface); \
     
    752621        iface##_METHODS \
    753622    };
     623#define ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
     624#endif /* ICOM_MSVTABLE_COMPAT */
    754625
    755626
     
    763634#define ICOM_CALL7(xfn, p,a,b,c,d,e,f,g) (p)->lpvtbl->fn##xfn(p,a,b,c,d,e,f,g)
    764635#define ICOM_CALL8(xfn, p,a,b,c,d,e,f,g,h) (p)->lpvtbl->fn##xfn(p,a,b,c,d,e,f,g,h)
     636#define ICOM_CALL9(xfn, p,a,b,c,d,e,f,g,h,i) (p)->lpvtbl->fn##xfn(p,a,b,c,d,e,f,g,h,i)
    765637#define ICOM_CALL10(xfn, p,a,b,c,d,e,f,g,h,i,j) (p)->lpvtbl->fn##xfn(p,a,b,c,d,e,f,g,h,i,j)
    766638
     
    775647 * Predeclare the interfaces
    776648 */
    777 DEFINE_OLEGUID(IID_IClassFactory,        0x00000001L, 0, 0);
     649DEFINE_OLEGUID(IID_IClassFactory,       0x00000001L, 0, 0);
    778650typedef struct IClassFactory IClassFactory, *LPCLASSFACTORY;
    779651
    780 DEFINE_OLEGUID(IID_IMalloc,                 0x00000002L, 0, 0);
     652DEFINE_OLEGUID(IID_IMalloc,             0x00000002L, 0, 0);
    781653typedef struct IMalloc16 IMalloc16,*LPMALLOC16;
    782654typedef struct IMalloc IMalloc,*LPMALLOC;
    783655
    784 DEFINE_OLEGUID(IID_IUnknown,                0x00000000L, 0, 0);
     656DEFINE_OLEGUID(IID_IUnknown,            0x00000000L, 0, 0);
    785657typedef struct IUnknown IUnknown, *LPUNKNOWN;
    786658
     
    798670struct IUnknown {
    799671    ICOM_VTABLE(IUnknown)* lpvtbl;
     672#if defined(ICOM_USE_COM_INTERFACE_ATTRIBUTE) && !defined(ICOM_CINTERFACE)
     673} __attribute__ ((com_interface));
     674#else
    800675};
     676#endif /* ICOM_US_COM_INTERFACE_ATTRIBUTE, !ICOM_CINTERFACE */
     677
    801678struct ICOM_VTABLE(IUnknown) {
    802     ICOM_METHOD2(HRESULT,QueryInterface,REFIID,riid, LPVOID*,ppvObj)
     679#ifdef ICOM_MSVTABLE_COMPAT
     680    long dummyRTTI1;
     681    long dummyRTTI2;
     682#endif /* ICOM_MSVTABLE_COMPAT */
     683
    803684#else /* ICOM_CINTERFACE */
    804685struct IUnknown {
    805 #ifndef ICOM_VIRTUAL_METHODS
    806     union {
    807         const void* lpvtbl;
    808         HRESULT (CALLBACK *fnQueryInterface)(IUnknown* me, REFIID riid, LPVOID* ppvObj);
    809     } t;
    810     inline int QueryInterface(REFIID a, LPVOID* b) { return ((IUnknown*)t.lpvtbl)->t.fnQueryInterface(this,a,b); }
    811 #else /* ICOM_VIRTUAL_METHODS */
     686
     687#endif /* ICOM_CINTERFACE */
     688
    812689    ICOM_METHOD2(HRESULT,QueryInterface,REFIID,riid, LPVOID*,ppvObj)
    813 #endif /* ICOM_VIRTUAL_METHODS */
    814 #endif /* ICOM_CINTERFACE */
    815690    ICOM_METHOD (ULONG,AddRef)
    816691    ICOM_METHOD (ULONG,Release)
     
    824699#define IUnknown_Release(p)            ICOM_CALL (Release,p)
    825700#endif
    826 
    827701
    828702/*****************************************************************************
     
    908782#define IMalloc_DidAlloc(p,a)   ICOM_CALL1(DidAlloc,p,a)
    909783#define IMalloc_HeapMinimize(p) ICOM_CALL (HeapMinimize,p)
    910 
    911 #ifndef __WINE__
    912 /* Duplicated for WINELIB */
    913 /*** IUnknown methods ***/
    914 #define IMalloc_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b)
    915 #define IMalloc_AddRef(p)             ICOM_CALL (AddRef,p)
    916 #define IMalloc_Release(p)            ICOM_CALL (Release,p)
    917 /*** IMalloc methods ***/
    918 #define IMalloc_Alloc(p,a)      ICOM_CALL1(Alloc,p,a)
    919 #define IMalloc_Realloc(p,a,b)  ICOM_CALL2(Realloc,p,a,b)
    920 #define IMalloc_Free(p,a)       ICOM_CALL1(Free,p,a)
    921 #define IMalloc_GetSize(p,a)    ICOM_CALL1(GetSize,p,a)
    922 #define IMalloc_DidAlloc(p,a)   ICOM_CALL1(DidAlloc,p,a)
    923 #define IMalloc_HeapMinimize(p) ICOM_CALL (HeapMinimize,p)
    924 #endif
    925784#endif
    926785
     
    993852HRESULT WINAPI CoRevokeClassObject(DWORD dwRegister);
    994853
    995 /*****************************************************************************
    996  * COM Server dll - exports
     854void WINAPI CoUninitialize16(void);
     855void WINAPI CoUninitialize(void);
     856
     857/*****************************************************************************
     858 *      COM Server dll - exports
    997859 */
    998860HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID * ppv);
Note: See TracChangeset for help on using the changeset viewer.