0

我正在枚举所有 DirectSound 输出设备并存储它们的描述以供以后在我的进程运行时使用。当我使用 OutputDebugStringW 检查结果时,我得到了正确的设备名称,但它附加了不必要的问号。即这个...

BOOL CALLBACK AudioPrivate::DSEnumProc(LPGUID lpGUID,
                                       LPCWSTR lpszDesc,
                                       LPCWSTR lpszDevName,
                                       LPVOID lpData) {
    pDeviceInfo[nDevices].lpGUID = lpGUID;
    pDeviceInfo[nDevices].lpszDesc = new WCHAR[wcslen(lpszDesc)];
    pDeviceInfo[nDevices].lpszDevName = new WCHAR[wcslen(lpszDevName)];

    ZeroMemory(pDeviceInfo[nDevices].lpszDesc, sizeof(WCHAR) * wcslen(lpszDesc));
    ZeroMemory(pDeviceInfo[nDevices].lpszDevName, sizeof(WCHAR) * wcslen(lpszDevName));

    memcpy(pDeviceInfo[nDevices].lpszDesc, lpszDesc, sizeof(WCHAR) * wcslen(lpszDesc));
    memcpy(pDeviceInfo[nDevices].lpszDevName, lpszDevName, sizeof(WCHAR) * wcslen(lpszDevName));

    OutputDebugStringW(L"\n");
    OutputDebugStringW(pDeviceInfo[nDevices].lpszDesc);
    OutputDebugStringW(L"\n");
    OutputDebugStringW(pDeviceInfo[nDevices].lpszDevName);
    OutputDebugStringW(L"\n");

    //vs
    OutputDebugString(L"\n");
    OutputDebugStringW(lpszDesc);
    OutputDebugStringW(L"\n");
    OutputDebugStringW(lpszDevName);
    OutputDebugStringW(L"\n");

    nDevices++;

    return TRUE;
}

...结果:

Primary Sound Driver????????????
????????

Primary Sound Driver



Speakers (Conexant SmartAudio HD)???????????
{0.0.0.00000000}.{0698bbc7-d0ba-4445-a5a7-a63b625c4298}?????????

Speakers (Conexant SmartAudio HD)
{0.0.0.00000000}.{0698bbc7-d0ba-4445-a5a7-a63b625c4298}

我正在将内存清空到我自己的字符串中,因此只有在 Enum Proc 提供的字符串中包含这些问号时才会发生这种情况,但正如所证明的那样,它们没有。为什么会这样?

4

2 回答 2

1

您必须为字符串终止符(也为 NULL 字符)保留空间,此行将只为字符串分配空间,没有终止符:

pDeviceInfo[nDevices].lpszDesc = new WCHAR[wcslen(lpszDesc)];

这是因为wcslen()返回没有终止符的字符串长度(请参阅参考资料)。只需更改为(当然对于所有字符串):

pDeviceInfo[nDevices].lpszDesc = new WCHAR[wcslen(lpszDesc) + 1];
pDeviceInfo[nDevices].lpszDevName = new WCHAR[wcslen(lpszDevName) + 1];

和:

ZeroMemory(pDeviceInfo[nDevices].lpszDesc, sizeof(WCHAR) * (wcslen(lpszDesc) + 1));
ZeroMemory(pDeviceInfo[nDevices].lpszDevName, sizeof(WCHAR) * (wcslen(lpszDevName) + 1));
于 2014-01-04T19:49:42.823 回答
1

我认为罪魁祸首隐藏在这里:

pDeviceInfo[nDevices].lpszDesc = new WCHAR[wcslen(lpszDesc)];

该字符串是 UNICODE,但仍作为 C 字符串处理,因此它需要一个 '\0' 终止符才能工作。

您必须再分配一个 WCHAR 才能为该终止符提供足够的空间。

pDeviceInfo[nDevices].lpszDesc = new WCHAR[wcslen(lpszDesc)+1];

如果ZeroMemory您替换memcpywcscpy

当您使用它时,您可能可以通过使用wcsdupor来省去麻烦_wcsdup

pDeviceInfo[nDevices].lpszDesc = wcsdup (lpszDesc);
于 2014-01-04T19:59:48.857 回答