commit d541cb606421272065c0a2ef95343b79336d3b17 Author: Jacek Caban Date: Wed Jul 25 11:18:45 2012 +0200 widl: Added support for type safe C interfaces diff --git a/include/objbase.h b/include/objbase.h index c366a28..d54377a 100644 --- a/include/objbase.h +++ b/include/objbase.h @@ -204,7 +204,7 @@ #define THIS_ INTERFACE *This, #define THIS INTERFACE *This -#define interface struct +#define interface __widl_interface #ifdef __WINESRC__ #define CONST_VTABLE diff --git a/include/rpcndr.h b/include/rpcndr.h index 514f1ce..195c634 100644 --- a/include/rpcndr.h +++ b/include/rpcndr.h @@ -137,8 +137,14 @@ typedef void (__RPC_USER *NDR_RUNDOWN)(void *context); typedef void (__RPC_USER *NDR_NOTIFY_ROUTINE)(void); typedef void (__RPC_USER *NDR_NOTIFY2_ROUTINE)(boolean flag); +#if !defined(__cplusplus) && defined(WIDL_TYPE_SAFE_C_INTERFACE) +#define __widl_interface union +#else +#define __widl_interface struct +#endif + #define DECLSPEC_UUID(x) -#define MIDL_INTERFACE(x) struct +#define MIDL_INTERFACE(x) __widl_interface struct _MIDL_STUB_MESSAGE; struct _MIDL_STUB_DESC; @@ -226,7 +232,7 @@ typedef struct _MIDL_STUB_MESSAGE void *pvDestContext; NDR_SCONTEXT *SavedContextHandles; LONG ParamNumber; - struct IRpcChannelBuffer *pRpcChannelBuffer; + __widl_interface IRpcChannelBuffer *pRpcChannelBuffer; PARRAY_INFO pArrayInfo; ULONG *SizePtrCountArray; ULONG *SizePtrOffsetArray; @@ -471,7 +477,7 @@ typedef struct _FULL_PTR_XLAT_TABLES { XLAT_SIDE XlatSide; } FULL_PTR_XLAT_TABLES, *PFULL_PTR_XLAT_TABLES; -struct IRpcStubBuffer; +__widl_interface IRpcStubBuffer; typedef ULONG error_status_t; typedef void * NDR_CCONTEXT; @@ -487,7 +493,7 @@ typedef struct _NDR_USER_MARSHAL_INFO_LEVEL1 ULONG BufferSize; void * (__WINE_ALLOC_SIZE(1) __RPC_API *pfnAllocate)(SIZE_T); void (__RPC_API *pfnFree)(void *); - struct IRpcChannelBuffer *pRpcChannelBuffer; + __widl_interface IRpcChannelBuffer *pRpcChannelBuffer; ULONG_PTR Reserved[5]; } NDR_USER_MARSHAL_INFO_LEVEL1; @@ -668,13 +674,13 @@ RPCRTAPI void RPC_ENTRY NdrAsyncServerCall( PRPC_MESSAGE pRpcMsg ); RPCRTAPI LONG RPC_ENTRY - NdrStubCall2( struct IRpcStubBuffer* pThis, struct IRpcChannelBuffer* pChannel, PRPC_MESSAGE pRpcMsg, DWORD * pdwStubPhase ); + NdrStubCall2( __widl_interface IRpcStubBuffer* pThis, __widl_interface IRpcChannelBuffer* pChannel, PRPC_MESSAGE pRpcMsg, DWORD * pdwStubPhase ); RPCRTAPI LONG RPC_ENTRY - NdrStubCall( struct IRpcStubBuffer* pThis, struct IRpcChannelBuffer* pChannel, PRPC_MESSAGE pRpcMsg, DWORD * pdwStubPhase ); + NdrStubCall( __widl_interface IRpcStubBuffer* pThis, __widl_interface IRpcChannelBuffer* pChannel, PRPC_MESSAGE pRpcMsg, DWORD * pdwStubPhase ); RPCRTAPI LONG RPC_ENTRY - NdrAsyncStubCall( struct IRpcStubBuffer* pThis, struct IRpcChannelBuffer* pChannel, PRPC_MESSAGE pRpcMsg, DWORD * pdwStubPhase ); + NdrAsyncStubCall( __widl_interface IRpcStubBuffer* pThis, __widl_interface IRpcChannelBuffer* pChannel, PRPC_MESSAGE pRpcMsg, DWORD * pdwStubPhase ); RPCRTAPI LONG RPC_ENTRY - NdrDcomAsyncStubCall( struct IRpcStubBuffer* pThis, struct IRpcChannelBuffer* pChannel, PRPC_MESSAGE pRpcMsg, DWORD * pdwStubPhase ); + NdrDcomAsyncStubCall( __widl_interface IRpcStubBuffer* pThis, __widl_interface IRpcChannelBuffer* pChannel, PRPC_MESSAGE pRpcMsg, DWORD * pdwStubPhase ); RPCRTAPI void* RPC_ENTRY NdrAllocate( PMIDL_STUB_MESSAGE pStubMsg, SIZE_T Len ) __WINE_ALLOC_SIZE(2); @@ -706,9 +712,9 @@ RPCRTAPI unsigned char* RPC_ENTRY RPCRTAPI void RPC_ENTRY NdrServerInitializeMarshall( PRPC_MESSAGE pRpcMsg, PMIDL_STUB_MESSAGE pStubMsg ); RPCRTAPI void RPC_ENTRY - NdrServerMarshall( struct IRpcStubBuffer *pThis, struct IRpcChannelBuffer *pChannel, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat ); + NdrServerMarshall( __widl_interface IRpcStubBuffer *pThis, __widl_interface IRpcChannelBuffer *pChannel, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat ); RPCRTAPI void RPC_ENTRY - NdrServerUnmarshall( struct IRpcChannelBuffer *pChannel, PRPC_MESSAGE pRpcMsg, + NdrServerUnmarshall( __widl_interface IRpcChannelBuffer *pChannel, PRPC_MESSAGE pRpcMsg, PMIDL_STUB_MESSAGE pStubMsg, PMIDL_STUB_DESC pStubDesc, PFORMAT_STRING pFormat, void *pParamList ); RPCRTAPI unsigned char* RPC_ENTRY diff --git a/tools/widl/header.c b/tools/widl/header.c index 0b2b9d5..5817fac 100644 --- a/tools/widl/header.c +++ b/tools/widl/header.c @@ -1094,6 +1094,7 @@ static void write_com_interface_end(FILE *header, type_t *iface) { int dispinterface = is_attr(iface->attrs, ATTR_DISPINTERFACE); const UUID *uuid = get_attrp(iface->attrs, ATTR_UUID); + type_t *parent_iface = type_iface_get_inherit(iface); if (uuid) write_guid(header, dispinterface ? "DIID" : "IID", iface->name, uuid); @@ -1104,10 +1105,9 @@ static void write_com_interface_end(FILE *header, type_t *iface) fprintf(header, "MIDL_INTERFACE(\"%s\")\n", uuid_string(uuid)); else fprintf(header, "interface "); - if (type_iface_get_inherit(iface)) + if (parent_iface) { - fprintf(header, "%s : public %s\n", iface->name, - type_iface_get_inherit(iface)->name); + fprintf(header, "%s : public %s\n", iface->name, parent_iface->name); fprintf(header, "{\n"); } else @@ -1125,7 +1125,7 @@ static void write_com_interface_end(FILE *header, type_t *iface) write_cpp_method_def(header, iface); indentation--; } - if (!type_iface_get_inherit(iface)) + if (!parent_iface) fprintf(header, " END_INTERFACE\n"); fprintf(header, "};\n"); if (uuid) @@ -1143,14 +1143,22 @@ static void write_com_interface_end(FILE *header, type_t *iface) indentation--; fprintf(header, " END_INTERFACE\n"); fprintf(header, "} %sVtbl;\n", iface->name); + fprintf(header, "#ifndef WIDL_TYPE_SAFE_C_INTERFACE\n"); fprintf(header, "interface %s {\n", iface->name); fprintf(header, " CONST_VTBL %sVtbl* lpVtbl;\n", iface->name); fprintf(header, "};\n"); + fprintf(header, "#else\n"); + fprintf(header, "union %s {\n", iface->name); + fprintf(header, " CONST_VTBL %sVtbl* lpVtbl;\n", iface->name); + if(parent_iface) + fprintf(header, " %s base;\n", parent_iface->name); + fprintf(header, "};\n"); + fprintf(header, "#endif\n"); fprintf(header, "\n"); fprintf(header, "#ifdef COBJMACROS\n"); /* dispinterfaces don't have real functions, so don't write macros for them, * only for the interface this interface inherits from, i.e. IDispatch */ - write_method_macro(header, dispinterface ? type_iface_get_inherit(iface) : iface, iface->name); + write_method_macro(header, dispinterface ? parent_iface : iface, iface->name); fprintf(header, "#endif\n"); fprintf(header, "\n"); fprintf(header, "#endif\n");