The function return type is WCHAR
. You are trying to return a C-style array of WCHAR
s. This isn't possible. You can instead return an std::wstring
object, so your code would look like this:
#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;
}
If the 4th parameter of SCardGetReaderDeviceInstanceId didn't output any data, you could just pass szDeviceInstanceId.size()+1
(+1 for null).
Also note, that the buffer will be allocated on the heap, unless SSO occurs (which is implementation defined, yet I don't think it would occur in any implementation in case of this long string).
As you can see the code is somewhat complex because of the differences in the management of the null-terminator. To make it simpler (but less beautiful in the C++ context) you can use std::wstring
only to return the string:
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);
}
Please note, that doing it like this might be a bit less performant as you have to allocate both WCHAR[255]
array and std::wstring
array. It isn't going to matter most of the time, but it might be worth using the first method in a very performance-sensitive context.
You can return the array in the C manner as well, however it isn't recommended to do that in C++.