2 Questions
1) if I do "make depend" than edit unknwn.idl (or any other idl) than do "make" should a new unknwn.h be compiled? Well it does not. If I "cd include" and "make" than nothing is done either. only if I do "make unknwn.h" it will compile.
2) In order for ATL to compile I need below code in my unknwn.h file. I could not fined a way to do it with WIDL. I have looked in Microsoft (vc6) header/idl and it looks they had the same problem. And below code was added by hand. Now if the answer to Q1 is "No not done automatically" than I guess I can submit a patch for unknwn.h only. could I also submit a patch to include/Makefile.in to remove unknwn.idl from the list of idl files so it will not accidentally over-write unknwn.h?
<unknwn.h snippet> ...
DEFINE_GUID(IID_IUnknown, 0x00000000, 0x0000, 0x0000, 0xc0,0x00, 0x00,0x00,0x00,0x00,0x00,0x46);
#if defined(__cplusplus) && !defined(CINTERFACE)
#if !defined(WINE_NO_UUIDOF) #include <wine/uuidof.h> extern "C++" { #endif
#ifdef ICOM_USE_COM_INTERFACE_ATTRIBUTE struct __attribute__((com_interface)) IUnknown #else struct IUnknown #endif { virtual HRESULT STDMETHODCALLTYPE QueryInterface( REFIID riid, void** ppvObject) = 0;
virtual ULONG STDMETHODCALLTYPE AddRef( ) = 0;
virtual ULONG STDMETHODCALLTYPE Release( ) = 0;
#if !defined(WINE_NO_UUIDOF) template <class Q> HRESULT STDMETHODCALLTYPE QueryInterface(Q** pp) { return QueryInterface(__uuidof(Q), (void**)pp); } #endif };
#if !defined(WINE_NO_UUIDOF) } // extern "C++" #endif
#else
... </unknwn.h snippet>
I have tried below simple idl code but it will go to all the wrong places
<bad unknwn.idl code> ...
interface IUnknown { typedef [unique] IUnknown *LPUNKNOWN;
HRESULT QueryInterface( [in] REFIID riid, [out, iid_is(riid)] void **ppvObject); ULONG AddRef(); ULONG Release(); cpp_quote("#if !defined(WINE_NO_UUIDOF)") cpp_quote("template <class Q>") cpp_quote("HRESULT STDMETHODCALLTYPE QueryInterface(Q** pp)") cpp_quote("{") cpp_quote(" return QueryInterface(__uuidof(Q), (void**)pp);") cpp_quote("}") cpp_quote("#endif")
}
cpp_quote("#if !defined(WINE_NO_UUIDOF)") cpp_quote("} /*extern C++*/") cpp_quote("#endif")
... </bad unknwn.idl code>
-----Original Message----- From: wine-devel-admin@winehq.org [mailto:wine-devel-admin@winehq.org]On Behalf Of Boaz Harrosh Sent: 31 December 2003 14:56 To: wine-devel mailing list Subject: unknwn.h: unknwn.idl
2 Questions
- if I do "make depend" than edit unknwn.idl (or any other idl) than do
"make" should a new unknwn.h be compiled? Well it does not. If I "cd include" and "make" than nothing is done either. only if I do "make unknwn.h" it will compile.
"make idl" will make all of the idl files. I'm not sure why it is done this way, but those files are only updated once in a blue moon anyway.
- In order for ATL to compile I need below code in my unknwn.h file. I
could not fined a way to do it with WIDL.
Use cpp_quote (grep for examples in other idl files).
I have looked in Microsoft (vc6) header/idl and it looks they had the same problem. And below code was added by hand. Now if the answer to Q1 is "No not done automatically" than I guess I can submit a patch for unknwn.h only. could I also submit a patch to include/Makefile.in to remove unknwn.idl from the list of idl files so it will not accidentally over-write unknwn.h?
No. You should use cpp_quote. It may be necessary to disable stuff in the .h generated file which you can do with: cpp_quote("#if 0") ... cpp_quote("#endif")
I have tried below simple idl code but it will go to all the wrong places
Where does it go? Maybe you need to also protect that bit of code with #if defined _cplusplus?
<bad unknwn.idl code> ...
interface IUnknown { typedef [unique] IUnknown *LPUNKNOWN;
HRESULT QueryInterface( [in] REFIID riid, [out, iid_is(riid)] void **ppvObject); ULONG AddRef(); ULONG Release(); cpp_quote("#if !defined(WINE_NO_UUIDOF)") cpp_quote("template <class Q>") cpp_quote("HRESULT STDMETHODCALLTYPE QueryInterface(Q** pp)") cpp_quote("{") cpp_quote(" return QueryInterface(__uuidof(Q), (void**)pp);") cpp_quote("}") cpp_quote("#endif")
}
cpp_quote("#if !defined(WINE_NO_UUIDOF)") cpp_quote("} /*extern C++*/") cpp_quote("#endif")
...
</bad unknwn.idl code>
"Robert Shearman" R.J.Shearman@warwick.ac.uk writes:
"make idl" will make all of the idl files. I'm not sure why it is done this way, but those files are only updated once in a blue moon anyway.
Because building them automatically causes a lot of headaches when generating dependencies. I'll get around to fixing that someday, but as you noted these files don't change often so for now you need to rebuild them explicitly (that's also why the .h files are in CVS, even though they are generated files).
ons, 31.12.2003 kl. 17.48 skrev Robert Shearman:
No. You should use cpp_quote. It may be necessary to disable stuff in the .h generated file which you can do with:
You can't use cpp_quote inside an interface definition. The quoted text would end up before the generated type, not inside. For interfaces, this even has a good reason: the IDL compiler must emit both C and C++ definitions for the interface, so the interface must be fully parsed first, and then the definitions generated. MS considers this a feature, as it lets you put typedefs and "import" statements inside the interface definition, without harm to the generated header, as the embedded typedefs and includes would still appear before the C/C++ definitions of the interface.
Even if cpp_quote statements could be parsed into the type instead of emitted directly, where would the result go? In the C definition of the interface? In the C++ definition? Both?
Apparently, MS didn't solve that problem, so widl hasn't either.
Ove Kaaven wrote:
ons, 31.12.2003 kl. 17.48 skrev Robert Shearman:
No. You should use cpp_quote. It may be necessary to disable stuff in the .h generated file which you can do with:
You can't use cpp_quote inside an interface definition. The quoted text would end up before the generated type, not inside. For interfaces, this even has a good reason: the IDL compiler must emit both C and C++ definitions for the interface, so the interface must be fully parsed first, and then the definitions generated. MS considers this a feature, as it lets you put typedefs and "import" statements inside the interface definition, without harm to the generated header, as the embedded typedefs and includes would still appear before the C/C++ definitions of the interface.
Even if cpp_quote statements could be parsed into the type instead of emitted directly, where would the result go? In the C definition of the interface? In the C++ definition? Both?
Apparently, MS didn't solve that problem, so widl hasn't either.
Exactly!
Alexandre please permit me to remove unknwn.idl from idl list in include/Makefile.in. And send a patch for unknwn.h. Look at this file if ever it will change the half of windows will stop. All that is COM will. The unknwn.idl file itself should stay in CVS because it is needed by other idl files. Just the unknwn.h Generation should be disabled. Or should we go Ove way with a patch file and an add execution line to "make idl"? I think first option is better since that file will never change. (and my mother said to never say never :))
Free life Boaz
Boaz Harrosh boaz@hishome.net writes:
Exactly!
Alexandre please permit me to remove unknwn.idl from idl list in include/Makefile.in. And send a patch for unknwn.h.
Of course not. Just add the needed code with cpp_quote in the .idl, adding #if 0 to disable the generated code. Check how Microsoft does it in the SDK headers.
-----Original Message----- From: Ove Kaaven [mailto:ovek@arcticnet.no] Sent: 01 January 2004 01:34 To: Robert Shearman Cc: Boaz Harrosh; wine-devel@winehq.org Subject: RE: unknwn.h: unknwn.idl
You can't use cpp_quote inside an interface definition.
True, but you can use cpp_quote to disable interface generation using cpp_quote("#if 0") ... cpp_quote("#endif"). This is how Microsoft do it with their unknwn.idl.
Apparently, MS didn't solve that problem, so widl hasn't either.
Microsoft caused the problem. What is the point of creating this automatic QueryInterface function? Is it that hard to pass in a matching IID with your interface pointer?
Robert Shearman wrote:
-----Original Message----- From: Ove Kaaven [mailto:ovek@arcticnet.no] Sent: 01 January 2004 01:34 To: Robert Shearman Cc: Boaz Harrosh; wine-devel@winehq.org Subject: RE: unknwn.h: unknwn.idl
You can't use cpp_quote inside an interface definition.
True, but you can use cpp_quote to disable interface generation using cpp_quote("#if 0") ... cpp_quote("#endif"). This is how Microsoft do it with their unknwn.idl.
point taken I'll have a look. But that means two things: 1) At .h file we have Dead C++ code with no use, then another c++ code duplicating most of the other code. 2) The code is duplicated any way. What is the difference if it is duplicated in two different files (.h & .idl) or if it is duplicated inside the same file? In any way it will have to be maintained by hand. One in MIDL syntax and one in C++ syntax. ( with cpp_quote( .. ) around it ).
And all that for something that will never change ( :) ) I go for change the makefile.
By the way. some thing funny. In MS headers from VC6 they do not have that thing in the .idl file at all. And the .h file is hand crafted. In one of the SDKs (the one I have) they have above solution but the supplied Header is not the result of that idl file. It looks like: Here is the header but if you accidentally compile the idl it will give you some ugly brother that works too.
Apparently, MS didn't solve that problem, so widl hasn't either.
Microsoft caused the problem. What is the point of creating this automatic QueryInterface function? Is it that hard to pass in a matching IID with your interface pointer?
Well, Personally I like it. One less thing That I can screw up. Either it matches or it does not compile. I let the compiler do my job any day. Any way ATL will not compile with out it. And it cannot be fixed either. because a long chain of definitions relay at that chip of information been carried by the compiler down 5 layers of code. Look at it this way. One MS programmer hard codes COM in C the other one in ATL. Which one will finish first? Well the second one wrote IE. (I know bad example on purpose :) )
ons, 31.12.2003 kl. 15.55 skrev Boaz Harrosh:
- In order for ATL to compile I need below code in my unknwn.h file. I
could not fined a way to do it with WIDL. I have looked in Microsoft (vc6) header/idl and it looks they had the same problem. And below code was added by hand.
If Microsoft couldn't solve it in their IDL compiler, I don't think widl could either, since it's meant to have MIDL-compatible syntax. If MIDL syntax can't do it, then widl isn't designed to handle it any better. I guess it might still be possible to design some widl extension to do it, but that won't be straightforward, and perhaps not a good idea either (having Wine's IDL files remain MIDL-compatible could be seen as a good thing).
If you must add a method this way, the only idea I have is to let this "make idl" thing patch the output of widl. Like, the Wine tree could contain a .diff file that adds your template thing, and after running widl, the makefile applies that patch to the generated .h file.