问题
I'm trying to use a function that calls SetupDiGetDeviceRegistryProperty with Delphi 7. The call is from the example function SetupEnumAvailableComPorts. It looks like this:
SetupDiGetDeviceRegistryProperty(
DevInfoHandle,
DeviceInfoData,
RegProperty,
@PropertyRegDataType,
nil,
0,
@RequiredSize
);
I get the error "Types of actual and formal parameters must be identical" on the parameters @PropertyRegDataType, and @RequiredSize. These parameters are declared:
var
RequiredSize: Cardinal;
PropertyRegDataType: DWORD;
MSDN describes these parameters as: "RequiredSize [out, optional] A pointer to a variable of type DWORD that receives the required size, in bytes, of the PropertyBuffer buffer that is required to hold the data for the requested property. This parameter is optional and can be NULL." and "PropertyRegDataType [out, optional] A pointer to a variable that receives the data type of the property that is being retrieved. This is one of the standard registry data types. This parameter is optional and can be NULL."
The declaration of SetupDiGetDeviceRegistryProperty (in SetupAPI.pas from JVCL) looks like:
function SetupDiGetDeviceRegistryProperty(
DeviceInfoSet: HDEVINFO;
const DeviceInfoData: TSPDevInfoData;
Property_: DWORD;
var PropertyRegDataType: DWORD;
PropertyBuffer: PBYTE;
PropertyBufferSize: DWORD;
var RequiredSize: DWORD
): BOOL; stdcall; {$EXTERNALSYM SetupDiGetDeviceRegistryProperty}
Since PropertyRegDataType and RequiredSize are var parameters, they should be able to be passed without the @ operator. In fact, if I remove the @ operators from the function call parameters, the code compiles, but crashes with an access violation (read of address 0). The original code was written for Delphi 7, so why would they use the @ operator on these parameters? What am I missing?
回答1:
Both of your variables PropertyRegDataType
and RequiredSize
should be declared as DWORD
. You actually declare RequiredSize
as Cardinal
although that is equivalent.
You are correct that since they are var
parameters you should not include the @
address operator.
It's hard to say why you are getting the error message without actually knowing what you pass for the other parameters.
EDIT
As commentators have pointed out, the JEDI translation is incorrect and PropertyRegDataType
, because it is an optional parameter, should be passed by value and typed as PDWORD
so that you are able to pass nil
.
回答2:
Delphi supports "reference parameters" via the var
and out
keywords and in some API conversions, the C-like pointers may be replaced by this convention; these paremeters are mandatory and must be passed as-is, w/o the address operator @
.
If the parameter declaration is left as pointer, allowing you to pass nil
, you have to ensure the parameter is optional -or- set it to valid memory memory location of appropriate size via the @
operator; no typechecking is performed in this case.
来源:https://stackoverflow.com/questions/5004854/windows-api-parameters-in-delphi-passing-var-parameter-with-or-without-opera