Угадайте размер буфера и вызовите функцию API или вызывайте ее каждый раз два раза, чтобы получить точный размер буфера - PullRequest
0 голосов
/ 29 июля 2010

Я хочу получить информацию о версии msi-пакета (ов).

Какой способ лучше?

Первый : угадывание достаточно большого буфера ивспомните, если он не подходит (ERROR_MORE_DATA)
1 вызов func против 3 вызовов func, и буфер может быть больше необходимого

Second : вызовФункция API, чтобы получить размер буфера и затем вызвать его, чтобы получить строку с (идеальным) совпадающим размером буфера
2 вызова func каждый раз с идеальным размером буфера

Это о(1 или 3) вызовы функций против 2 вызовов функций каждый раз.

Есть ли лучший метод для этой "проблемы"?

Я надеюсь получить обобщенный ответ (предположим,вызывающая функция действительно занимает много времени и / или размер буфера может сильно различаться (от 10 байтов до 200 мегабайт) для дальнейшей записи кода.: -)

псевдокод:

Первый:

StringBuffer = 10 // (byte) guessing returned string will fit in 10 bytes  

result = MsiGetProductInfoW(
  product,
  INSTALLPROPERTY_VERSIONSTRING,
  VersionString,
  StringBuffer
); //maybe it fits in 10

if result = ERROR_MORE_DATA then //doesnt fit in 10 so recall to get the correct buffer size
begin
  MsiGetProductInfoW(
    product,
    INSTALLPROPERTY_VERSIONSTRING,
    nil,
    StringBuffer
  );

  Inc(StringBuffer); // cause null-terminated string

  // recall it with matching
  MsiGetProductInfoW(
    product,
    INSTALLPROPERTY_VERSIONSTRING,
    VersionString,
    StringBuffer
  );
end;

Второй:

StringBuffer = 0;

// get buffer size
MsiGetProductInfoW(
  product,
  INSTALLPROPERTY_VERSIONSTRING,
  nil,
  StringBuffer
);

Inc(StringBuffer); // cause null-terminated string

// use it with the correct buffersize
MsiGetProductInfoW(
  product,
  INSTALLPROPERTY_VERSIONSTRING,
  VersionString,
  StringBuffer
);

Спасибо!

1 Ответ

1 голос
/ 29 июля 2010

В первом параметре вы можете пропустить второй вызов, потому что даже при неудачном первом вызове необходимый размер должен быть сохранен в StringBuffer.

Это делает выбор (1 или 2) против (всегда 2).Это должно быть достаточно ясно.Кроме того, не составит труда найти буфер разумного размера, который пройдет 90 +% времени.

...