I just installed C++ Builder 12 and wanted to compile an ancient piece of software that uses a TFileStream to read and write to c style buffers. For instance:
DWORD MyFileStream::Read (BYTE *Buffer, DWORD Count)
{
try
{
if (File)
return File->Read(Buffer, Count) ;
}
catch(...)
{
LastError = GetLastError() ;
return MY_ERROR_READ ;
}
return 0x00 ;
}
This still compiles ok in 32 bit, but (going from c++ Builder 11.3 to 12) it now doesn't compile anymore in 64 bit. So, after 20 years or so I had to go and have a look at TFileStream in the help file and it appears to solely use a DynamicArray ?
Confused ? Why does it compile in 32 bit then ? I have a feeling the help file is not complete ?? And more importantly, how do I fix this without creating a dynamic array (assuming that is still possible) ?
The error:
call to member function 'Read' is ambiguous
[C++ Error] System.Classes.hpp(1756, 36): candidate function
[C++ Error] System.Classes.hpp(1771, 38): candidate function
[C++ Error] System.Classes.hpp(1777, 36): candidate function not viable: no known conversion from 'BYTE *' (aka 'unsigned char *') to 'System::Sysutils::TBytes &' (aka 'DynamicArray<unsigned char> &') for 1st argument
[C++ Error] System.Classes.hpp(1779, 38): candidate function not viable: no known conversion from 'BYTE *' (aka 'unsigned char *') to 'System::Sysutils::TBytes &' (aka 'DynamicArray<unsigned char> &') for 1st argument
[C++ Error] System.Classes.hpp(1773, 36): candidate function not viable: requires 3 arguments, but 2 were provided
[C++ Error] System.Classes.hpp(1775, 38): candidate function not viable: requires 3 arguments, but 2 were provided
That is incorrect. It still has overloads for working with raw buffers.
The real culprit is that
Read()(andWrite()) has additional overloads under 64-bit only, which are not documented yet but you would see them if you look at the declarations inSystem.Classes.hpp:This means that under 64-bit only, the 2-param
Read()which you are trying to call now accepts bothLongIntandNativeInttypes for the buffer size, and sinceDWORDis implicitly convertible to both types, that is why your code is now ambiguous under 64-bit but not under 32-bit.To solve this, you would need to explicitly tell the compiler which overload you want to call. You can either:
DWORDto the desired integer type, eg:Readmethod itself to the desired overload type before calling it, eg: