I have a very serious problem with Embarcadero C++Builder 10.2.2 when compiling a mid-sized in-house application with the "classic" BCC32 compiler.
There's a class to wrap up some DLL functions responsible for reading the number of available hardware USB-interface boxes used for a connection interface and their serial numbers as string. The code below compiles without a flaw when using BCC32, as well as with BCC32c, but during runtime the BCC32 version crashes horribly, while everything works well with BCC32c.
The number of connected devices is sucessfully detected in both cases (which is 2
in my setup) but instead of returning the correct UsbDeviceSerialNo
in
FDllPointers.GetUSBDeviceSN()
(for example 126739701012387721219679016621
) there's only garbage in there:
��\x18
.
In the second iteration of
for (unsigned int UsbDeviceNo = 0; UsbDeviceNo < 32; ++UsbDeviceNo)
there's an 'Access violation at address 00000000...' in the line
memset(UsbDeviceSerialNo, 0, SerNoBufferSize);
std::size_t TComUsbRoot::RefreshInterfaces()
{
// Note: This function does not work correctly when compiled
// with Borland BCC32 due to offset errors and AVs!!
// I don't have a clue, why this is the case at the moment.
const unsigned int SerNoBufferSize = 40;
unsigned long UsbDeviceMask = 0;
char UsbDeviceSerialNo[SerNoBufferSize];
// Clear the current interfaces
FInterfaces.clear(); // <-- std::vector<TComUsbInterface>
// Get the currently available interface count
int InterfaceCount = FDllPointers.GetAvailableUSBDevices(&UsbDeviceMask); // <-- int WINAPI CC_GetAvailableUSBDevices(unsigned long * DeviceMask); (from DLL)
// We need at least one interface to proceed
if (!InterfaceCount)
return 0;
// Check all USB device numbers
for (unsigned int UsbDeviceNo = 0; UsbDeviceNo < 32; ++UsbDeviceNo)
{
// Check the USB device mask
if (((1 << UsbDeviceNo) & UsbDeviceMask) != 0)
{
// Set the serial no to zeroes
memset(UsbDeviceSerialNo, 0, SerNoBufferSize);
// Get the USB device's serial number
int Result = FDllPointers.GetUSBDeviceSN(
UsbDeviceNo,
UsbDeviceSerialNo,
SerNoBufferSize
);
if (Result != 0)
{
throw Except(
std::string("ComUSB: Error while reading the USB device's serial number")
);
}
// Convert the serial number to wstring
std::wstring SerialNo(CnvToWStr(UsbDeviceSerialNo));
// Create a new interface object with the USB device's parameters
TComUsbInterface Interface(
*this,
UsbDeviceNo,
SerialNo,
FDllPointers,
FLanguage
);
// Add it to the vector
FInterfaces.push_back(Interface);
}
}
// Return the size of the interfaces vector
return FInterfaces.size();
}
I simply don't know what's wrong here, as everything is allright with the new, Clang-based compiler. Unfortunately I cannot use the new compiler for this project, as the code completion (which is crappy and compiler-based in C++Builder and feels like using an early BETA edition of somtehing) makes the IDE crash 5 times an hour and the overall compilation time can be simply unbearable, even with the use of precompiled headers.