Forum > Windows

REFIID definition

(1/3) > >>

440bx:
Hello,

I just noticed that in redef.inc, the following definitions (among many others) appear:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} --- type  PIID    = PGUID;  TIID    = TGUID;  REFIID  = TIID;  THANDLE = HANDLE; 
In the above a REFIID is the same as a TIID which is the same as a TGUID.

However, MSDN defines REFIID as
--- Code: C  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} --- typedef IID* REFIID; which would make a REFIID a _pointer_ to an IID (which is the same as a GUID), therefore a REFIID should be a _pointer_ to a GUID not just equal to a GUID.

If that definition is actually incorrect, it is very surprising that it has not been already caught because REFIID is a type that is extensively used in some parts of the Windows API.

I also checked the Jwa... definitions and it is defined the same way there but the functions that use a REFIID as a parameter are declared as being var or constref, effecitively passing a pointer to the IID (but those definitions are not parallel to the C definitions.)

Note, in other files, the REFIID is passed as a "const" parameter thereby depending on FPC passing a pointer to the REFIID in spite of the fact that the FPC documentation clearly states that, unlike Delphi, "const" does not necessarily imply that the parameter will be passed by reference.

Did I miss something or is that definition actually incorrect ?

Thank you for your help.

Remy Lebeau:

--- Quote from: 440bx on March 30, 2025, 07:01:38 pm ---Note, in other files, the REFIID is passed as a "const" parameter thereby depending on FPC passing a pointer to the REFIID in spite of the fact that the FPC documentation clearly states that, unlike Delphi, "const" does not necessarily imply that the parameter will be passed by reference.

--- End quote ---

In Delphi/FreePascal, it is not uncommon practice to declare a pointer parameter which is not allowed to be nil by its API (and a REFIID is never nil) to be passed as a (const) reference instead to simply user coding.

An IID is too big to fit in a single CPU register when passed by value, so passing it by (const) reference will undoubtedly pass it as a pointer.

440bx:
Thank you for the reply Remy.


--- Quote from: Remy Lebeau on March 30, 2025, 07:41:08 pm ---An IID is too big to fit in a single CPU register when passed by value, so passing it by (const) reference will undoubtedly pass it as a pointer.

--- End quote ---
I understand that.

My concern is that is if the type REFIID is used in a structure/record then the definition will be incorrect. 

In addition to that definition requiring something like "const", "var" or "constref" to be correct, in a record/structure there is no "trick" to make it correct.

That definition makes me very uncomfortable because the room for something not working as intended is quite large.

ETA: corrected typo

nanobit:
It looks like you have found a real source of bugs.
FPC declares a few api functions with riid:REFIID (value parameter) which is wrong.
These should declare "const" (possible with "stdcall" convention) or "constref".
But less confusing would be TIID (with const, constref) and PIID.

marcov:
IIRC refiid is mostly used in const expressions for interfaces.

The swallowing of the pointer is necessary, because Delphi/FPC do interface refcounting automatically.

Navigation

[0] Message Index

[#] Next page

Go to full version