-2

I am getting the below error when compiling the C++ project.

Error C2664 'BOOL CryptBinaryToStringW(const BYTE *,DWORD,DWORD,LPWSTR,DWORD *)': cannot convert argument 4 from 'std::unique_ptr>' to 'LPWSTR'

at the below line of code:

CryptBinaryToString(reinterpret_cast<const BYTE*>(strData.c_str()), dwSize,
        dwOptions, pwszBuffer, &dwLength);

And also I am getting the below error:

Error C2679 binary '=': no operator found which takes a right-hand operand of type 'std::unique_ptr>' (or there is no acceptable conversion)

at the below line:

sBase64 = pwszBuffer;

Below is the complete code:

bool EMRReader::EncodeBase64(DWORD dwSize, const std::string& strData, wstring& sBase64)
{
    DWORD dwOptions = CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF;
    DWORD dwLength = 0;

    BOOL bRet = CryptBinaryToString(reinterpret_cast<const BYTE*>(strData.c_str()), dwSize,
        dwOptions, 0, &dwLength);

    if (!bRet)
        return bRet;

    std::unique_ptr<std::wstring> pwszBuffer = std::make_unique<std::wstring>(dwLength + 1);
    if (!pwszBuffer)
        return FALSE;

    SecureZeroMemory(pwszBuffer.get(), (dwLength + 1) * sizeof(wchar_t));
    CryptBinaryToString(reinterpret_cast<const BYTE*>(strData.c_str()), dwSize,
        dwOptions, pwszBuffer, &dwLength);

    sBase64 = pwszBuffer;

    return TRUE;
}

Could anyone please help me to resolve these errors?

ndrwnaguib
  • 5,623
  • 3
  • 28
  • 51
John Paul Coder
  • 313
  • 1
  • 12
  • 2
    1) Why `std::unique_ptr` instead of `std::wstring`? 2) What's unclear about the error? `pwszBuffer->data ()` instead of `pwszBuffer` in `CryptBinaryToString` call (note, to use it, you need to compile your program with C++-17)? – Algirdas Preidžius Sep 20 '19 at 16:39

1 Answers1

0

You're assigning a std::unique_ptr<wstring> object to a variable of type wstring that is not allowed. If you want to assign the value of pwszBuffer to a variable of type wstring, you should get the unique_ptr's value and then assign it to the variable.

You can get the value of std::unique_ptr by calling its * operator:

sBase64 = *pwszBuffer;


Edit: If you want to pass a std::unique_ptr to a function, you have two ways:

  1. Pass it by reference:
void func(std::unique_ptr<std::wstring>& input_ptr) {
    // Do something...
}

and then use it simply:

std::unique_ptr<std::wstring> function_input;
func(function_input);

Or 2. If you want to pass it by value, move it:

void func(std::unique_ptr<std::wstring>& 
input_ptr) {
    // Do something...
}

and then pass it with std::move:

std::unique_ptr<std::wstring> function_input;
func(std::move(function_input));

You should be aware that in this case after moving the function_input, It owns nothing and holds a nullptr and you shouldn't use it out of the func.

related

mrazimi
  • 337
  • 1
  • 3
  • 12
  • Thank you @Mrazimi, I am also getting the below error: Error C2664 'BOOL CryptBinaryToStringW(const BYTE *,DWORD,DWORD,LPWSTR,DWORD *)': cannot convert argument 4 from 'std::unique_ptr>' to 'LPWSTR' – John Paul Coder Sep 21 '19 at 15:50
  • In the below line of code: CryptBinaryToString(reinterpret_cast(strData.c_str()), dwSize, dwOptions, pwszBuffer, &dwLength); – John Paul Coder Sep 21 '19 at 15:50
  • @JohnPaulCoder I've edited the answer and added the solution for this error. – mrazimi Sep 21 '19 at 16:42