Windows API Parametre i Delphi - passerende var parameter med eller uden @ operator?

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg forsøger at bruge en funktion, der kalder SetupDiGetDeviceRegistryProperty sammen med Delphi 7.
Opkaldet er fra eksempelfunktionen SetupEnumAvailableComPorts. Det ser sådan ud: [19] [20]


SetupDiGetDeviceRegistryProperty(
  DevInfoHandle,
  DeviceInfoData,
  RegProperty,
  @PropertyRegDataType,
  nil,
  0,
  @RequiredSize
);


Jeg får fejlen 'Typer af faktiske og formelle parametre skal være identiske' på parametrene @PropertyRegDataType og @RequiredSize. Disse parametre erklæres:


var
  RequiredSize: Cardinal;
  PropertyRegDataType: DWORD;


MSDN beskriver disse parametre som: 'RequiredSize [[out, optional]] En peger på en variabel af typen DWORD, der modtager den krævede størrelse i byte af PropertyBuffer-bufferen, der skal indeholde dataene for den ønskede ejendom. parameter er valgfri og kan være NULL. 'og ' PropertyRegDataType [[out, optional]] En pointer til en variabel, der modtager datatypen for den egenskab, der hentes. Dette er en af ​​standardregistret data Denne parameter er valgfri og kan være NULL. '


Erklæringen fra SetupDiGetDeviceRegistryProperty (i SetupAPI.pas fra JVCL) ligner: [21]


function SetupDiGetDeviceRegistryProperty(
  DeviceInfoSet: HDEVINFO;
  const DeviceInfoData: TSPDevInfoData; 
  Property\_: DWORD;
  var PropertyRegDataType: DWORD; 
  PropertyBuffer: PBYTE; 
  PropertyBufferSize: DWORD;
  var RequiredSize: DWORD
): BOOL; stdcall; {$EXTERNALSYM SetupDiGetDeviceRegistryProperty}


Da PropertyRegDataType og RequiredSize er var parametre, skal de kunne bestås uden @ operatøren. Faktisk, hvis jeg fjerner @ operatørerne fra funktionsopkaldsparametrene, kompilerer koden, men går i stykker med en adgangsfejl (læs af adresse 0). Den originale kode blev skrevet til Delphi 7, så hvorfor ville de bruge @ operatøren på disse parametre? Hvad mangler jeg? [22]

Bedste reference


Begge dine variabler PropertyRegDataType og RequiredSize bør angives som DWORD. Du erklærer faktisk RequiredSize som Cardinal, selv om det er ækvivalent.


Du er korrekt, at da de er var parametre, skal du ikke inkludere @ adressearrangøren.


Det er svært at sige, hvorfor du får fejlmeddelelsen uden at vide, hvad du passer for de andre parametre.


EDIT


Som kommentatorer har påpeget, er JEDI-oversættelsen forkert, og PropertyRegDataType, fordi det er en valgfri parameter, skal sendes efter værdi og indtastes som PDWORD, så du kan passere nil .

Andre referencer 1


Delphi understøtter 'referenceparametre' via var og out nøgleordene og i nogle API-konverteringer kan de C-lignende pointers erstattes af denne konvention; Disse parametre er obligatoriske og skal bestilles, uden adresseleder @.

Hvis parameterdeklarationen efterlades som peger, så du kan passere nil, skal du have til sikre, at parameteren er valgfri - eller - indstil den til gyldig hukommelseshukommelse, hvor passende størrelse er angivet via [[@ operatør; Ingen typechecking udføres i dette tilfælde .