2010-07-29 52 views
0

我想要检索MSI封装(S)猜一个缓冲区大小和调用API函数或每次调用它twotimes得到确切的缓冲区大小

有什么更好的办法的版本信息?

首先:猜测的缓冲区足够大,并且记得,如果它不适合(ERROR_MORE_DATA)
1功能调用与3 FUNC电话和缓冲区可以更大然后需要

第二:调用API函数来获取缓冲区的大小,然后调用它用(完美)匹配缓冲区大小
2 FUNC得到的字符串调用了一个完美的缓冲区大小,每次

这是关于(1或3)函数调用(s)与每次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

在您的第一个选项中,您可以跳过第二个呼叫,因为即使在第一次呼叫失败时,所需的大小也应存储在StringBuffer中。

这使得选择(1或2)与(总是2)。这应该足够清楚。此外,要想出一个合理大小的缓冲区并不难,那将会超过90%的时间。