某些api需要计数字符。
// Why did they choose cch in these functions.
HRESULT StringCchCopyW(
__out LPWSTR pszDest,
__in size_t cchDest,
__in LPCWSTR pszSrc
);
errno_t wcscpy_s(
wchar_t *strDestination,
size_t numberOfElements,
const wchar_t *strSource
);
DWORD WINAPI GetCurrentDirectoryW(
__in DWORD nBufferLength, // Count of Chars
__out LPWSTR lpBuffer
);
有些api需要字节数。
// What do you prefer cch vs cb function.
// Do cch functions almost useful?
HRESULT StringCbCopyW(
__out LPWSTR pszDest,
__in size_t cbDest,
__in LPCWSTR pszSrc
);
BOOL WINAPI ReadFile(
__in HANDLE hFile,
__out LPVOID lpBuffer,
__in DWORD nNumberOfBytesToRead,
__out_opt LPDWORD lpNumberOfBytesRead,
__inout_opt LPOVERLAPPED lpOverlapped
);
// Why did they choose cb in these structures.
// Because there are some apis uses cb, I always should see MSDN.
typedef struct _LSA_UNICODE_STRING {
USHORT Length; // Count of bytes.
USHORT MaximumLength; // Count of bytes.
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
typedef struct _FILE_RENAME_INFO {
BOOL ReplaceIfExists;
HANDLE RootDirectory;
DWORD FileNameLength; // Count of bytes.
WCHAR FileName[1];
} FILE_RENAME_INFO, *PFILE_RENAME_INFO;
设计函数或数据结构时,如何确定cb或cch?为什么呢? 为了给呼叫者设计更好的api,我应该知道什么呢?
答案 0 :(得分:3)
如果返回的数据是字符串,则应返回字符数,因为字节数通常是无用的。但如果它是通用二进制数据(而不是特定的字符串),那么显然字符数没有任何意义,所以使用字节数。
至于原因:
我认为LSA_UNICODE_STRING
保持字节数的原因是它与UNICODE_STRING
兼容,后者又用于NtCreateFile。但NtCreateFile
接收FILE_OPEN_BY_FILE_ID
参数,该参数实际上将UNICODE_STRING
视为指向LONGLONG
值,而不表示字符串...所以字节数在那里更有意义,虽然我说它总体上是一个糟糕的设计:
FILE_OPEN_BY_FILE_ID:
ObjectAttributes
参数指定的文件名包含文件的8字节文件引用号。
答案 1 :(得分:0)
如果你注意到,你提到的第一组函数都是ASCII函数,因此在这种情况下没有区别 - 字节数是字符数。这是因为(通常,无论如何)单个ASCII字符的大小恰好是一个字节。
第二组是unicode函数/结构。在这种情况下,字符不能保证只有一个字节大小 - 如果是UTF16格式,它们将是两个字节宽,在UTF32中它们将是四个,而在UTF8中,它们(通常)可以是任何地方一到四个字节宽。
特别是对于UTF8数据的情况,如果你创建一个缓冲区,通常你会留出一定数量的字节,这取决于字符大小在字符数方面可能有很多种长度。我对你提出的大多数功能/结构都不太熟悉,但如果它与它有关,我也不会感到惊讶。
要回答你的问题,如果你正在使用ASCII,你可以使用任何一种方法 - 它没有任何区别。但是,如果使用可变长度编码(例如UTF8),是否使用其中一种编码取决于您是否只对所涉及的字符感兴趣,或者是否还需要考虑它们的编码。