为什么这两个“等效”代码不会以相同的行为结束? [英] Why those two "equivalent" codes does not end up with the same behaviour?
问题描述
开启一个单独的帖子,我正在帮助乔治·爱德华兹使用 BLE API 。
我确保我发布的代码(使用因子分解的模板)等同于原始代码。但是当乔治发送到嵌入式设备时,行为是不同的:
I'm pretty sure the code I posted (using templates for factorization) is equivalent to the original one. But when George sends it to the embedded device, the behaviour is different:
通过阅读代码,有人可以帮助弄清楚
By reading the code, can someone help figuring out what's the difference between those two pieces of code (they appear to be completely equivalent from my point of view)?
代码的版本1
Version1 of the code (with this code, BLE descriptor for the characteristic is accessible):
// create descriptor
GattAttribute nameDescr( BLE_UUID_DESCRIPTOR_CHAR_USER_DESC, (uint8_t *)"Percentage", strlen("Percentage"));
// create descriptor array
GattAttribute *descriptors[] = {&nameDescr};
// create characteristic
WriteOnlyArrayGattCharacteristic<uint8_t,sizeof(percentageValue)>
percentageChar( PercentageUUID,
percentageValue,
GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_EXTENDED_PROPERTIES,
descriptors,
sizeof(descriptors) / sizeof(GattAttribute*) );
// create characteristic array
GattCharacteristic *characteristics[] = {&percentageChar, &timeChar, &UseProfileChar};
// create service
GattService newService(newServiceUUID, characteristics, sizeof(characteristics) / sizeof(GattCharacteristic *));
代码版本2 (使用此代码,BLE描述符 可访问):
Version2 of the code (with this code, BLE descriptor for the characteristic is not accessible):
template <typename T, unsigned NUM_ELEMENTS, template <typename T, unsigned NUM_ELEMENTS> class CharacType>
class CharacteristicWithNameDescrptorHelper
{
public:
CharacteristicWithNameDescrptorHelper( const UUID &uuid,
T valuePtr[NUM_ELEMENTS],
uint8_t additionalProperties,
const std::string& name ) :
// create descriptor
descriptor( BLE_UUID_DESCRIPTOR_CHAR_USER_DESC, (uint8_t *)name.c_str(), name.size() )
{
// create descriptor array
descriptors[0] = &descriptor;
// create characteristic:
charac = new CharacType<T,NUM_ELEMENTS>( uuid, valuePtr, additionalProperties, descriptors, 1 );
}
~CharacteristicWithNameDescrptorHelper()
{
delete charac;
}
CharacType<T,NUM_ELEMENTS>* charac;
GattAttribute descriptor;
GattAttribute *descriptors[1];
};
// create charcteristic, descriptor and descriptor array
CharacteristicWithNameDescrptorHelper<uint8_t,sizeof(percentageValue),WriteOnlyArrayGattCharacteristic>
percentageChar( PercentageUUID,
percentageValue,
GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_EXTENDED_PROPERTIES,
"Percentage" );
// create characteristic array
GattCharacteristic *characteristics[] = {percentageChar.charac};
// create service
GattService newService(newServiceUUID, characteristics, sizeof(characteristics) / sizeof(GattCharacteristic *));
CharacteristicWithNameDescrptorHelper 代码。
请注意,代码不能轻易地被我帮助的人调试,因为它是一个嵌入式代码。因此,很难以不同于代码审查的方式调查此问题。
Note that the code cannot be easily debugged by the person I'm helping because it's an embedded code. So it's hard to investigate the issue in a different manner than doing a "code review".
推荐答案
显然, GattAttribute
不会从传递给其构造函数的指针复制数据,而只保存指针。
Apparently, GattAttribute
does not copy the data from the pointer you pass to its constructor, but merely holds the pointer.
在原始代码中是没有问题,因为它是一个字符串常数,它总是有效的。在第二个版本中,你传递了一个指向来自 string
的数据的指针,该字符串很快被销毁,因此指针变得无效。
In the original code this was no problem because it was passed a string literal which is always valid. In the second version, you passed it a pointer to data from a string
which was soon destructed, so the pointer became invalid.
这可以通过将字符串放在 GattAttribute
旁边并调用 c_str()
This can be fixed by putting the string in a member stored alongside the GattAttribute
and calling c_str()
on the member.
这篇关于为什么这两个“等效”代码不会以相同的行为结束?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!