digitalmars.D.learn - Use of GUID constants
- KlausO (65/65) Mar 09 2016 Dear list,
- =?UTF-8?Q?Ali_=c3=87ehreli?= (8/17) Mar 09 2016 Without any experience with COM or (current) Windows programming, just
- KlausO (13/31) Mar 10 2016 Ok, but what's the intention behind defining GUIDs as enums in the first...
- Mike Parker (12/16) Mar 10 2016 Probably just an implementation error, i.e. someone not fully
- KlausO (42/57) Mar 10 2016 For GUIDs you often have to take the address (e.g. for calls to
- Mike Parker (12/30) Mar 10 2016 Personally I would just declare one immutable value in module
- thedeemon (9/15) Mar 10 2016 There is one good reason for doing it VisualD way.
- Kagamin (3/6) Mar 11 2016 Declarations come from mingw and mingw doesn't have uuid.lib:
- Kagamin (2/2) Mar 11 2016 Oh, it was
Dear list, I use DMD 2.070.0 I try to access COM Interfaces via the declarations in core.sys.windows.* I have some problems and maybe someone could give me a usage hint. Have a look at the following (relatively meaningless) sample program which demonstrates the problem. IMHO the problem is that GUID constants are declared as enums in the winapi bindings (see src\druntime\import\core\sys\windows\uuid.d). Within the dclient.d sample which comes with dmd they are explicitely defined as GUIDs: GUID IID_IHello = { 0x00421140, 0, 0, [0xC0, 0, 0, 0, 0, 0, 0, 0x46] }; So maybe they should be declared as "extern GUID ..." because they also seem to be defined in windows\lib\uuid.lib which comes with DMD. What do you think ? Thanks -- KlausO Sample program: import std.stdio; import std.utf; import core.stdc.stdlib; import core.sys.windows.windows; import core.sys.windows.com; import core.sys.windows.objidl; bool CreateCompoundDoc(const wstring filename) { IStorage storage; HRESULT hr = StgCreateDocfile( toUTF16z(filename), STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_DIRECT | STGM_CREATE, 0, &storage); if (S_OK == hr) { IUnknown pUnk; // // Does not compile: // // Error: function core.sys.windows.unknwn.IUnknown.QueryInterface(const(GUID)* riid, void** pvObject) is not callable using argument types (const(GUID), void**) // hr = storage.QueryInterface(IID_IUnknown, cast(void**)&pUnk); // // Does not compile either: // // Error: GUID(0u, cast(ushort)0u, cast(ushort)0u, [cast(ubyte)192u, cast(ubyte)0u, cast(ubyte)0u, cast(ubyte)0u, cast(ubyte)0u, cast(ubyte)0u, cast(ubyte)0u, cast(ubyte)70u]) is not an lvalue // hr = storage.QueryInterface(&IID_IUnknown, cast(void**)&pUnk); } } int main(string[] argv) { HRESULT hr=CoInitialize(null); // Initialize OLE if (FAILED(hr)) { printf("OLE 2 failed to initialize\n"); return EXIT_FAILURE; } CreateCompoundDoc("hello.doc"); // Only call this if CoInitialize worked CoUninitialize(); return EXIT_SUCCESS; }
Mar 09 2016
On 03/09/2016 10:35 AM, KlausO wrote:IUnknown pUnk; // // Does not compile: // // Error: function core.sys.windows.unknwn.IUnknown.QueryInterface(const(GUID)* riid, void** pvObject) is not callable using argument types (const(GUID),void**)// hr = storage.QueryInterface(IID_IUnknown, cast(void**)&pUnk);Without any experience with COM or (current) Windows programming, just by looking at that error message, the following may work: IID unknown = IID_IUnknown; // (Apparently, IID is an alias for const(GUID).) storage.QueryInterface(&unknown, /* ... */); Ali
Mar 09 2016
Ok, but what's the intention behind defining GUIDs as enums in the first place ? Why not defining them as const(GUID) and let the linker sort them out ? Is there a recommended way to declare/define constants (e.g. as enums or consts) ? In C (separate compilation) they are declared as "EXTERN_C const GUID" and you use one C file to define this GUIDs for the Linker. Thanks -- KlausO For the record, found two somehow related issues in bugzilla: https://issues.dlang.org/show_bug.cgi?id=14309 https://issues.dlang.org/show_bug.cgi?id=4092 Am 09.03.2016 um 23:20 schrieb Ali Çehreli:On 03/09/2016 10:35 AM, KlausO wrote: > IUnknown pUnk; > > // > // Does not compile: > // > // Error: function > core.sys.windows.unknwn.IUnknown.QueryInterface(const(GUID)* riid, > void** pvObject) is not callable using argument types (const(GUID), void**) > // > hr = storage.QueryInterface(IID_IUnknown, cast(void**)&pUnk); Without any experience with COM or (current) Windows programming, just by looking at that error message, the following may work: IID unknown = IID_IUnknown; // (Apparently, IID is an alias for const(GUID).) storage.QueryInterface(&unknown, /* ... */); Ali
Mar 10 2016
On Thursday, 10 March 2016 at 10:16:30 UTC, KlausO wrote:Ok, but what's the intention behind defining GUIDs as enums in the first place ?Probably just an implementation error, i.e. someone not fully appreciating how GUIDs are intended to be used.Is there a recommended way to declare/define constants (e.g. as enums or consts) ?Generally, you should use a manifest constant, e.g. enum myConst = 10; Unless you need to take the address, then you should use immutable: immutable myConst = 10; The value of a manifest constant is substituted for the symbol at the point of use and is not stored in the data segment (so has no memory address), but an immutable (or const) variable is stored in the data segment.
Mar 10 2016
For GUIDs you often have to take the address (e.g. for calls to QueryInterface), so I think phobos does not correctly implement this. In the meantime I took a look at the VisualD project which accesses the COM interfaces of visual studio. They solve the problem by using the following idiom (see https://github.com/D-Programming-Language/visuald/blob/master sdk/port/servprov.d for an example): const GUID IID_IServiceProvider = IServiceProvider.iid; interface IServiceProvider : IUnknown { static const GUID iid = { 0x6d5140c1, 0x7436, 0x11ce, [ 0x80, 0x34, 0x00, 0xaa, 0x00, 0x60, 0x09, 0xfa ] }; public: /* [local] */ HRESULT QueryService( /* [in] */ in GUID* guidService, /* [in] */ in IID* riid, /* [out] */ void **ppvObject); } If every interface declaration contains the static iid member this enables you to provide something similar to the the __uuidof operator in VisualC (see https://msdn.microsoft.com/de-de/library/zaah6a61.aspx). In VisualD something along that line is implemented in the qi_cast template (see https://github.com/D-Programming-Language/visuald/blob/master/stdext/com.d). Is the above pair (const GUID and static member) the right way to declare this idiom or would the following be better ? Both compile and seem to be equivalent (in terms of achieving the same goal): enum IID IID_IServiceProvider = { 0x6d5140c1, 0x7436, 0x11ce, [ 0x80, 0x34, 0x00, 0xaa, 0x00, 0x60, 0x09, 0xfa ] }; interface IServiceProvider : IUnknown { static immutable GUID iid = IID_IServiceProvider; public: /* [local] */ HRESULT QueryService( /* [in] */ in GUID* guidService, /* [in] */ in IID* riid, /* [out] */ void **ppvObject); } Thanks for your insights -- KlausO Am 10.03.2016 um 14:49 schrieb Mike Parker:On Thursday, 10 March 2016 at 10:16:30 UTC, KlausO wrote:Ok, but what's the intention behind defining GUIDs as enums in the first place ?Probably just an implementation error, i.e. someone not fully appreciating how GUIDs are intended to be used.Is there a recommended way to declare/define constants (e.g. as enums or consts) ?Generally, you should use a manifest constant, e.g. enum myConst = 10; Unless you need to take the address, then you should use immutable: immutable myConst = 10; The value of a manifest constant is substituted for the symbol at the point of use and is not stored in the data segment (so has no memory address), but an immutable (or const) variable is stored in the data segment.
Mar 10 2016
On Thursday, 10 March 2016 at 14:52:16 UTC, KlausO wrote:For GUIDs you often have to take the address (e.g. for calls to QueryInterface), so I think phobos does not correctly implement this.Yes, that was my meaning.Is the above pair (const GUID and static member) the right way to declare this idiom or would the following be better ? Both compile and seem to be equivalent (in terms of achieving the same goal): enum IID IID_IServiceProvider = { 0x6d5140c1, 0x7436, 0x11ce, [ 0x80, 0x34, 0x00, 0xaa, 0x00, 0x60, 0x09, 0xfa ] }; interface IServiceProvider : IUnknown { static immutable GUID iid = IID_IServiceProvider; public: /* [local] */ HRESULT QueryService( /* [in] */ in GUID* guidService, /* [in] */ in IID* riid, /* [out] */ void **ppvObject); }Personally I would just declare one immutable value in module scope and be done with it. It really just doesn't matter. Unless you're following some sort of style guide, personal preference rules the day. I don't know if Rainers has a special reason for what he did with the Visual D code or if it was personal preference. As for Phobos, the Win32 API in Phobos as it stands now was a recent addition. Though it existed as a third-party package for several years, it may still have some kinks to work out and may not follow the Phobos style guide in some places.
Mar 10 2016
On Thursday, 10 March 2016 at 15:48:14 UTC, Mike Parker wrote:Personally I would just declare one immutable value in module scope and be done with it. It really just doesn't matter. Unless you're following some sort of style guide, personal preference rules the day. I don't know if Rainers has a special reason for what he did with the Visual D code or if it was personal preference.There is one good reason for doing it VisualD way. It defines and uses smart pointers ComPtr(ISomething) where you can just write auto x = ComPtr!ISomeInterface(someObject); and if someObject has a different COM type this constructor will QueryInterface() for the proper interface, and to do this it needs to know its IID, so a common way to get IID knowing just an interface type is really helpful.
Mar 10 2016
On Wednesday, 9 March 2016 at 18:35:31 UTC, KlausO wrote:So maybe they should be declared as "extern GUID ..." because they also seem to be defined in windows\lib\uuid.lib which comes with DMD.Declarations come from mingw and mingw doesn't have uuid.lib: https://issues.dlang.org/show_bug.cgi?id=15482
Mar 11 2016
Oh, it was https://github.com/D-Programming-Language/druntime/pull/1472
Mar 11 2016