首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法从“WCHAR[256]”转换为“WCHAR”

无法从“WCHAR[256]”转换为“WCHAR”
EN

Stack Overflow用户
提问于 2022-09-22 13:45:23
回答 1查看 72关注 0票数 0

我有一个函数,它使用winscord.h函数SCardGetReaderDeviceInstanceId。

代码语言:javascript
复制
    WCHAR SCardInstanceId(SCARDCONTEXT phContext, LPTSTR szReaderName) {
    WCHAR    szDeviceInstanceId[256];
    DWORD    cchDeviceInstanceId = 256;

    long lReturn = SCardGetReaderDeviceInstanceId(phContext, szReaderName, szDeviceInstanceId, &cchDeviceInstanceId);

    if (lReturn != SCARD_S_SUCCESS) {
        cout << "Failed SCardGetReaderDeviceInstanceId, errorcode: " << std::hex << std::setfill('0') << std::setw(8) << lReturn << endl;
        exit(1);
    }
    
    return szDeviceInstanceId;
}

但是它给了我返回线上的错误信息。

代码语言:javascript
复制
E0120   return value type does not match the function type

代码语言:javascript
复制
Error   C2440   'return': cannot convert from 'WCHAR [256]' to 'WCHAR'

这里有什么问题吗?我该怎么解决呢?

我不能将函数类型更改为WCHAR 256,它甚至是一个类型?

EN

回答 1

Stack Overflow用户

发布于 2022-09-22 20:13:48

函数返回类型为WCHAR。您正在尝试返回一个C样式的WCHAR数组,这是不可能的。您可以返回一个std::wstring对象,因此您的代码如下所示:

代码语言:javascript
复制
#include <string>
std::wstring SCardInstanceId(SCARDCONTEXT phContext, LPTSTR szReaderName) {
    std::wstring szDeviceInstanceId;
    DWORD cchDeviceInstanceId = 255;
    szDeviceInstanceId.resize(cchDeviceInstanceId);
    // I think it is safer to resize to 255 chars as it is implementation defined if the internal array has the null-terminator.
    // If it does and you resize to 256, you will end up with a 257-element array...

    long lReturn = SCardGetReaderDeviceInstanceId(phContext, szReaderName, szDeviceInstanceId.data(), &cchDeviceInstanceId); // from c++17
    // long lReturn = SCardGetReaderDeviceInstanceId(phContext, szReaderName, &szDeviceInstanceId[0], &cchDeviceInstanceId); 
    // before c++17 'data' returns const reference, so SCardGetReaderDeviceInstanceId couldn't modify the buffer (compilation error)

    szDeviceInstanceId.resize(cchDeviceInstanceId-1); // shrink the string length to the length actually occupied by characters
    // -1 because cchDeviceInstanceId is length including null-terminator (according to docs), and resize expects length excluding null
    

    if (lReturn != SCARD_S_SUCCESS) {
        cout << "Failed SCardGetReaderDeviceInstanceId, errorcode: " << std::hex << std::setfill('0') << std::setw(8) << lReturn << endl;
        exit(1);
    }
    
    return szDeviceInstanceId;
}

如果SCardGetReaderDeviceInstanceId的第四个参数没有输出任何数据,则只需传递szDeviceInstanceId.size()+1 (+1为null)。还要注意的是,缓冲区将在堆上分配,除非发生SSO (这是定义的实现,但我不认为在任何实现中都会出现这个长字符串)。

如您所见,代码有些复杂,因为空终止符的管理存在差异。为了使它更简单(但在C++上下文中不那么漂亮),您只能使用std::wstring返回字符串:

代码语言:javascript
复制
std::wstring SCardInstanceId(SCARDCONTEXT phContext, LPTSTR szReaderName) {
    WCHAR    szDeviceInstanceId[255];
    DWORD    cchDeviceInstanceId = 255;

    long lReturn = SCardGetReaderDeviceInstanceId(phContext, szReaderName, szDeviceInstanceId, &cchDeviceInstanceId);

    if (lReturn != SCARD_S_SUCCESS) {
        cout << "Failed SCardGetReaderDeviceInstanceId, errorcode: " << std::hex << std::setfill('0') << std::setw(8) << lReturn << endl;
        exit(1);
    }
    
    return std::wstring(szDeviceInstanceId);
}

请注意,这样做可能会降低性能,因为您必须同时分配WCHAR[255]数组和std::wstring数组。在大多数情况下,这并不重要,但在性能敏感的上下文中使用第一种方法可能是值得的。

您也可以返回数组in the C manner,但是不建议在C++中这样做。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73815776

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档