为什么这两个“等效”代码不会以相同的行为结束? [英] Why those two "equivalent" codes does not end up with the same behaviour?

查看:180
本文介绍了为什么这两个“等效”代码不会以相同的行为结束?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

开启一个单独的帖子,我正在帮助乔治·爱德华兹使用 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆