You can't do that as the COM standard specifies also the ABI. A COM interface is a pointer to a virtual table; it is *not* a struct. That's just an implementation detail in C.
On 11/10/2012 08:48 PM, max@mtew.isa-geek.net wrote:
From: Max TenEyck Woodbury max+git@mtew.isa-geek.net
tools/widl/header.c | 14 ++++++++++++++ 1 files changed, 14 insertions(+), 0 deletions(-)
diff --git a/tools/widl/header.c b/tools/widl/header.c index 2f275c7..965dcbc 100644 --- a/tools/widl/header.c +++ b/tools/widl/header.c @@ -1159,6 +1159,17 @@ static void write_com_interface_start(FILE *header, const type_t *iface) fprintf(header,"#define __%s_%sINTERFACE_DEFINED__\n\n", iface->name, dispinterface ? "DISP" : ""); }
+static void write_interface_data_macro(FILE *header, const type_t *iface) +{
- if (type_iface_get_inherit(iface))
- write_interface_data_macro(header, type_iface_get_inherit(iface));
- fprintf(header, "#ifdef %s_IFACE_DATA\n", iface->name);
- fprintf(header, " %s_IFACE_DATA\n", iface->name);
- fprintf(header, "#endif /* defined %s */\n", iface->name);
+}
static void write_com_interface_end(FILE *header, type_t *iface) { int dispinterface = is_attr(iface->attrs, ATTR_DISPINTERFACE); @@ -1214,6 +1225,9 @@ static void write_com_interface_end(FILE *header, type_t *iface) fprintf(header, "} %sVtbl;\n", iface->name); fprintf(header, "interface %s {\n", iface->name); fprintf(header, " CONST_VTBL %sVtbl* lpVtbl;\n", iface->name);
- write_interface_data_macro(header, iface);
- fprintf(header, "};\n"); fprintf(header, "\n"); fprintf(header, "#ifdef COBJMACROS\n");
bye michael
I mentioned this a few days ago. It would have helped if you had raised this point then.
As it stands, it is simply a way to adding data members to an aggregate with an interface. In that sense it is not an addition to the interface since the Vtbl pointer remains exactly as before. The new information is not part of the interface as such. Putting it in the same 'struct' as the Vtbl is simply a way of enforcing the association. If you do not define a <iface>_IFACE_DATA macro, nothing happens.
On 11/11/2012 05:00, Max TenEyck Woodbury wrote:
I mentioned this a few days ago. It would have helped if you had raised this point then.
As it stands, it is simply a way to adding data members to an aggregate with an interface.
Data members to an aggregate? What are you talking about and what it has to do with interface definition?
In that sense it is not an addition to the interface since the Vtbl pointer remains exactly as before. The new information is not part of the interface as such. Putting it in the same 'struct' as the Vtbl is simply a way of enforcing the association. If you do not define a <iface>_IFACE_DATA macro, nothing happens.
On 11/11/2012 01:01 AM, Nikolay Sivov wrote:
On 11/11/2012 05:00, Max TenEyck Woodbury wrote:
I mentioned this a few days ago. It would have helped if you had raised this point then.
As it stands, it is simply a way to adding data members to an aggregate with an interface.
Data members to an aggregate? What are you talking about and what it has to do with interface definition?
An aggregate is a collection of information, like a class, struct or union.
Some aggregates include 'interface's, a COM, OLE or RPC thingy. The interface can have only methods defined, but those methods might want access to some additional data. To get to that data, the method now has to build a pointer to the containing aggregate and reference the data through that pointer. This introduces complications to the code since the data may not be in same place in the aggregate in each instance where the interface is used. You need a slightly different code sequence for each different place the method is needed. However, the source code will be virtually identical for each instance.
This patch allows those aggregate data members associated with the interface, which are not technically part of the interface, to be placed in a fixed relation to the interfaces Vtbl pointer. (Practically the Vtbl pointer is the interface.) By establishing such a relationship, the need to convert from the pointer to the interface (specifically to its Vtbl pointer) to a pointer to its containing aggregate in order to get to the relevant data is removed.
Now, technically, the associated data is not part of the interface. It is part of the aggregate containing and implementing the interface. Moving the declaration from the aggregate to the end of the struc for the interface is a hack that lets simpler and more general code to be generated.
So, it's a hack, that you only use if you want to, to speed up execution and simplify maintenance.
On 11/11/2012 07:12 AM, Max TenEyck Woodbury wrote:
On 11/11/2012 01:01 AM, Nikolay Sivov wrote:
On 11/11/2012 05:00, Max TenEyck Woodbury wrote:
I mentioned this a few days ago. It would have helped if you had raised this point then.
As it stands, it is simply a way to adding data members to an aggregate with an interface.
Data members to an aggregate? What are you talking about and what it has to do with interface definition?
An aggregate is a collection of information, like a class, struct or union.
Your mixing up terminology.
Some aggregates include 'interface's, a COM, OLE or RPC thingy. The interface can have only methods defined, but those methods might want access to some additional data. To get to that data, the method now has to build a pointer to the containing aggregate and reference the data through that pointer. This introduces complications to the code since the data may not be in same place in the aggregate in each instance where the interface is used. You need a slightly different code sequence for each different place the method is needed. However, the source code will be virtually identical for each instance.
This patch allows those aggregate data members associated with the interface, which are not technically part of the interface, to be placed in a fixed relation to the interfaces Vtbl pointer. (Practically the Vtbl pointer is the interface.) By establishing such a relationship, the need to convert from the pointer to the interface (specifically to its Vtbl pointer) to a pointer to its containing aggregate in order to get to the relevant data is removed.
Please check how a C compiler is laying out structs in memory. In both cases the data is at a fixed offset (calculated at compile time) in relation to the interface.
Now, technically, the associated data is not part of the interface. It is part of the aggregate containing and implementing the interface. Moving the declaration from the aggregate to the end of the struc for the interface is a hack that lets simpler and more general code to be generated.
So, it's a hack, that you only use if you want to, to speed up execution and simplify maintenance.
It is a hack that breaks the ABI (sizeof(interface) == sizeof(void*)), doesn't improves the generated code, doesn't simplify maintenance at all, quite the contrary. This sounds more like trolling than a serious attempt to improve Wine.
bye michael
On 11/11/2012 03:05 PM, Michael Stefaniuc wrote:
On 11/11/2012 07:12 AM, Max TenEyck Woodbury wrote:
On 11/11/2012 01:01 AM, Nikolay Sivov wrote:
On 11/11/2012 05:00, Max TenEyck Woodbury wrote:
I mentioned this a few days ago. It would have helped if you had raised this point then.
As it stands, it is simply a way to adding data members to an aggregate with an interface.
Data members to an aggregate? What are you talking about and what it has to do with interface definition?
An aggregate is a collection of information, like a class, struct or union.
Your mixing up terminology.
Please excuse the confusion. I learned that usage when I worked for DEC in the 1980's.
Some aggregates include 'interface's, a COM, OLE or RPC thingy. The interface can have only methods defined, but those methods might want access to some additional data. To get to that data, the method now has to build a pointer to the containing aggregate and reference the data through that pointer. This introduces complications to the code since the data may not be in same place in the aggregate in each instance where the interface is used. You need a slightly different code sequence for each different place the method is needed. However, the source code will be virtually identical for each instance.
This patch allows those aggregate data members associated with the interface, which are not technically part of the interface, to be placed in a fixed relation to the interfaces Vtbl pointer. (Practically the Vtbl pointer is the interface.) By establishing such a relationship, the need to convert from the pointer to the interface (specifically to its Vtbl pointer) to a pointer to its containing aggregate in order to get to the relevant data is removed.
Please check how a C compiler is laying out structs in memory. In both cases the data is at a fixed offset (calculated at compile time) in relation to the interface.
I believe you are confused here. The relative addresses in the original may change if changes are made to the aggregate. If you want to tell the compiler which aggregate member you want to use, you need to use a pointer to the aggregate. It has no way to figure out what you are talking about unless you give it that without this hack.
Now, technically, the associated data is not part of the interface. It is part of the aggregate containing and implementing the interface. Moving the declaration from the aggregate to the end of the struc for the interface is a hack that lets simpler and more general code to be generated.
So, it's a hack, that you only use if you want to, to speed up execution and simplify maintenance.
It is a hack that breaks the ABI (sizeof(interface) == sizeof(void*)), doesn't improves the generated code, doesn't simplify maintenance at all, quite the contrary. This sounds more like trolling than a serious attempt to improve Wine.
That depends on exactly what you call the 'interface'. If you call the Vtbl the interface, the size does not change. If you call the 'struct' containing the Vtbl the interface (which someone else pointed out is only an artifact of the implementation technique), it changes. So, as with most hacks, you have to be careful what you ask for. I might change my mind if you point out an existing non-contrived example of using sizeof(<interface>) that this would break.
The real question is ;Could it be useful?'. I think the answer is 'yes'.
On 11/11/2012 03:00 AM, Max TenEyck Woodbury wrote:
I mentioned this a few days ago. It would have helped if you had raised this point then.
I tried, but your email made no sense. You didn't even mention that you're talking about COM interfaces.
As it stands, it is simply a way to adding data members to an aggregate with an interface. In that sense it is not an addition to the interface since the Vtbl pointer remains exactly as before. The new information is not part of the interface as such. Putting it in the same 'struct' as the Vtbl is simply a way of enforcing the association. If you do not define a <iface>_IFACE_DATA macro, nothing happens.
bye michael