Files
vxWorks/h/comBase.h
2025-08-20 18:25:46 +08:00

244 lines
7.1 KiB
C

/* comBase.h - VxDCOM Base Definitions */
/* Copyright (c) 1999 Wind River Systems, Inc. */
/*
modification history
--------------------
01l,21dec01,nel Use offset for DCC instead of adjustment in COM_ADJUST_THIS.
01k,10dec01,dbs diab build
01j,13jul01,dbs allow multiple vtables to be defined in same file
01i,02jul01,dbs fix typo in vtbl formats
01h,29jun01,dbs fix vtbl format for T3 compilers
01g,27jun01,dbs fix warnings from COM_VTABLE macro
01f,25jun01,dbs rename vtbl macros to COM_VTBL_XXX
01e,22jun01,dbs add WIDL_ADJUST_THIS macro
01d,20jun01,dbs fix C build
01c,15jun01,dbs fix vtbl layouts for known compilers
01b,19jul00,dbs add basic C support
01a,21sep99,dbs created from comLib.h
*/
#ifndef __INCcomBase_h
#define __INCcomBase_h
/*
* Always include vxWorks.h for basic types - IDL will need to define
* those Win32-like types that aren't present in vxWorks.h but the
* base OS definitions should always be present.
*/
#include <vxWorks.h>
/* Some common macros... */
#define __RPC_FAR
#define __RPC_USER
#define __RPC_STUB
#ifndef interface
#define interface struct
#endif
#ifndef STDCALL
#define STDCALL
#endif
#ifdef __cplusplus
#define EXTERN_C extern "C"
#define STDMETHOD(method) virtual HRESULT STDMETHODCALLTYPE method
#define STDMETHOD_(type,method) virtual type STDMETHODCALLTYPE method
#else
#define EXTERN_C extern
#define STDMETHOD(method) HRESULT STDMETHODCALLTYPE (*method)
#define STDMETHOD_(type,method) type STDMETHODCALLTYPE (*method)
#endif
#define DECLSPEC_UUID(x)
#define STDMETHODCALLTYPE STDCALL
#define STDMETHODIMP HRESULT STDMETHODCALLTYPE
#define STDMETHODIMP_(type) type STDMETHODCALLTYPE
#define __RPC_FAR
#define __RPC_USER
#define __RPC_STUB
#define PRPC_MESSAGE void*
/*
* WIDL_CPP_REF is defined as a true C++ reference when compiling for
* C++, and as a pointer when compiling for plain C. This is used by
* WIDL when emitting typedefs, etc, generated from IDL.
*/
#ifdef __cplusplus
#define WIDL_CPP_REF &
#else
#define WIDL_CPP_REF *
#endif
/**************************************************************************
*
* -- VTable Layout --
*
* Whether we're using C++ or plain C, we must generate a vtbl that is
* compatible with the C++ compiler for this architecture. Currently we
* know about the two different versions of 'gcc' where pre-egcs
* versions (as shipped with Tornado 2.0) use the old-style entries
* with this-offsets held in the table itself, but later versions
* (egcs/gcc2.95 and beyond) can use one DWORD per entry, and the
* compiler supplies an inline 'thunk' code-fragment to adjust the
* this-ptr. However, for VxWorks AE 1.x (T3.x) compilers, this feature
* is not enabled, so the vtbl format is gcc2-offsets (i.e. the old
* style).
*
* To define a vtable structure, the usage is:-
*
* typedef struct
* {
* COM_VTBL_BEGIN
* COM_VTBL_ENTRY (HRESULT, Method1, (int x));
* COM_VTBL_ENTRY (HRESULT, Method2, (long x));
* COM_VTBL_END
* } IFooVtbl;
*
* To build a const vtable the usage is:-
*
* COM_VTABLE(IFoo) IFoo_proxy_vtbl = {
* COM_VTBL_HEADER
* COM_VTBL_METHOD (&IFoo_Method1_proxy),
* COM_VTBL_METHOD (&IFoo_Method2_proxy)
* };
*
* Note carefully the use of commas and semicolons at the end of
* the lines.
*
***************************************************************************
*
* Firstly, enumerate what the possible vtable formats are.
*
**************************************************************************/
#define COM_VTBL_FORMAT_GCC2_OFFSET 1
#define COM_VTBL_FORMAT_GCC2_THUNKS 2
#define COM_VTBL_FORMAT_GCC3 3
/**************************************************************************
*
* Now, we figure out which version of GCC and which platform its
* running on, and then select the appropriate COM_VTBL_FORMAT_XXX
* macro to enforce one (and *only* one) of the vtable formats, for
* VxWorks (AE) targets. Host-builds (Linux, Solaris) must define the
* macro in their repsective makefiles.
*
***************************************************************************/
#if !defined(unix)
#ifdef __GNUC__
# if (__GNUC__ == 2)
# define COM_VTBL_FORMAT COM_VTBL_FORMAT_GCC2_OFFSET
# elif (__GNUC__ == 3)
# define COM_VTBL_FORMAT COM_VTBL_FORMAT_GCC3
# endif
#elif defined (__DCC__)
# define COM_VTBL_FORMAT COM_VTBL_FORMAT_GCC2_OFFSET
#endif
#endif
/**************************************************************************
*
* Now we take the decision we have just made, and generate the
* correct vtable layout, calling-macros, etc.
*
***************************************************************************/
#if (COM_VTBL_FORMAT == COM_VTBL_FORMAT_GCC2_OFFSET)
/**************************************************************************
*
* This is the vtable format for gcc WITHOUT THUNKS. This format has an
* adjustment to the 'this' pointer stored at each call-site (vtable
* entry) and the caller has to adjust 'this' before dispatching the
* call.
*
***************************************************************************/
#define COM_VTBL_BEGIN short __adj; short __pad; void* pRTTI;
#define COM_VTBL_ENTRY(rt, fn, args) \
short __adj##fn; short __pad##fn; rt (*fn) args
#define COM_VTBL_END
#define COM_VTBL_HEADER 0,0,0,
#define COM_VTBL_METHOD(fn) 0,0,fn
#define COM_ADJUST_THIS(pThis) (void*)(((char*)pThis)+pThis->lpVtbl->__adjQueryInterface)
#define COM_VTBL_SYMBOL com_vtbl_format_gcc2_offset
#elif (COM_VTBL_FORMAT == COM_VTBL_FORMAT_GCC2_THUNKS)
/**************************************************************************
*
* This is the vtable format for gcc2.x WITH THUNKS. This format simply
* stores the pointer at each call-site and the compiler supplies
* inline fragments of code to adjust the 'this' pointer (these are the
* thunks) so each vtable entry is simply a function pointer.
*
***************************************************************************/
#define COM_VTBL_BEGIN short __adj; short __pad; void* pRTTI;
#define COM_VTBL_ENTRY(rt, fn, args) rt (*fn) args
#define COM_VTBL_END
#define COM_VTBL_HEADER 0,0,0,
#define COM_VTBL_METHOD(fn) fn
#define COM_ADJUST_THIS(pThis) pThis
#define COM_VTBL_SYMBOL com_vtbl_format_gcc2_thunks
#elif (COM_VTBL_FORMAT == COM_VTBL_FORMAT_GCC3)
/**************************************************************************
*
* This is the vtable format for gcc3. This format is the same as the
* 'with thunks' format, but there is no 'header' i.e. the 'this'
* pointer offset is not stored in the vtable at all.
*
***************************************************************************/
#define COM_VTBL_BEGIN
#define COM_VTBL_ENTRY(rt, fn, args) rt (*fn) args
#define COM_VTBL_END
#define COM_VTBL_HEADER
#define COM_VTBL_METHOD(fn) fn
#define COM_ADJUST_THIS(pThis) pThis
#define COM_VTBL_SYMBOL com_vtbl_format_gcc3
#else
#error Unknown GCC vtable format - unable to determine host/compiler.
#endif
#define DECLARE_COM_VTBL_SYMBOL_HERE int COM_VTBL_SYMBOL = 0;
#define COM_VTABLE(itf) \
extern int COM_VTBL_SYMBOL; \
static void widlref_##itf(int x) \
{ widlref_##itf (x+COM_VTBL_SYMBOL); } \
const itf##Vtbl
#endif /* __INCcomBase_h */