从 C++ 函数返回整个自定义类型数组
Returning a whole custom type array from a C++ function
我正在开发一个 c++ 应用程序,用一些信息填充蓝牙阵列。它基于BLE_API的mbed平台,但我认为这无关紧要。我有以下代码,我正在尝试将其重构为一个函数。
GattAttribute nameDescr1(BLE_UUID_DESCRIPTOR_CHAR_USER_DESC, (uint8_t *)"Percentage", strlen("Percentage"));
GattAttribute *pdescriptors[] = { &nameDescr1 };
PercentageFill(PercentageUUID, valueBytes.getPointer(),
valueBytes.getNumValueBytes(), HeartRateValueBytes::MAX_VALUE_BYTES,
GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_EXTENDED_PROPERTIES,
pdescriptors,
sizeof(pdescriptors) / sizeof(GattAttribute*)),
到目前为止,我已经得到了这个:
GattAttribute produceName (char title[]) {
GattAttribute nameDescr(BLE_UUID_DESCRIPTOR_CHAR_USER_DESC, (uint8_t *)title, strlen(title));
GattAttribute *descriptors[] = { &nameDescr };
return descriptors;
}
但是,可以预见的是,我抛出了一个错误:
我错误:不存在合适的构造函数来从"GattAttribute *[1]"转换为"GattAttribute"
可以看到它为什么抛出这个,但不确定我应该如何返回整个数组,因为这是"PercentFill"构造函数所需的格式。
谢谢。
更新:
为了提供完整的上下文,以下是我正在设置的其他特征(每个都有不同的名称(:
NewService(BLE &_ble, uint8_t percentageFill, uint8_t replacementDue) :
ble(_ble),
valueBytes(percentageFill),
PercentageFill(PercentageUUID, valueBytes.getPointer(),
valueBytes.getNumValueBytes(), HeartRateValueBytes::MAX_VALUE_BYTES,
GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_EXTENDED_PROPERTIES,
pdescriptors,
sizeof(pdescriptors) / sizeof(GattAttribute*)),
Time( TimeUUID,
&replacementDue,
GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_EXTENDED_PROPERTIES,
tdescriptors,
sizeof(tdescriptors) / sizeof(GattAttribute*)),
UseProfile( UseProfileUUID,
&controlPointValue,
GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_EXTENDED_PROPERTIES,
Udescriptors,
sizeof(Udescriptors) / sizeof(GattAttribute*)),) {
setupService();
}
该函数produceName
声明返回一个GattAttribute
对象,但您正在尝试返回指向GattAttribute
对象的指针数组。差别很大。
但这并不是代码中最糟糕的部分。如果修复声明返回类型以便代码生成,则会遇到一个更糟糕的问题,该问题将导致未定义的行为:返回指向局部变量的指针。函数返回后,这些局部变量将不复存在,并且无法使用指向它们的任何指针。
首先:请注意,原始代码中的pdescriptors
数组只有一个元素长。因此,指向对象的直接指针可以正常工作,或者如果百分比填充不需要指针数组,则可以正常工作。我们可以通过传递指针到指针和大小为 1 来模拟这一点。请注意:原始代码中的sizeof(...)/sizeof(...)
计算也意味着返回 1,当您引入函数边界时(特别是当您将数组作为参数传递给函数时(,这变得很棘手。
除此之外,您的问题有些不清楚:您是否打算实现不同的GattAttribute
值?如果没有,您可以执行以下操作:
void updatePercentage(WhateverTypeValueBytesIs valueBytes) {
GattAttribute nameDescr(BLE_UUID_DESCRIPTOR_CHAR_USER_DESC, (uint8_t *)"Percentage", strlen("Percentage"));
GattAttribute * ptr = &nameDescr; // needed, because we want to pass pointer-to-pointer-to-nameDescr
PercentageFill(PercentageUUID, valueBytes.getPointer(),
valueBytes.getNumValueBytes(), HeartRateValueBytes::MAX_VALUE_BYTES,
GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_EXTENDED_PROPERTIES,
&ptr, 1), /* are we sure about trailing comma here? */
// other relevant trailing code?
}
从您在评论中提到的有关无法访问的复制构造函数的错误消息来看,GattAttribute
可能是一个常规构造函数,因此无需在那里创建其他函数。如果你想把这个特定的GattAttribute
变成你可以隐藏在函数界面后面并在需要时"查找"的东西,那么你可以把它变成这样的单例(例如,存在实现相同目标的其他方法(:
GattAttribute * getNameDescriptor(void) {
static GattAttribute nameDescr(BLE_UUID_DESCRIPTOR_CHAR_USER_DESC, (uint8_t *)"Percentage", strlen("Percentage"));
return &nameDescr;
}
然后你可以像这样使用该函数:
void updatePercentage(WhateverTypeValueBytesIs valueBytes) {
GattAttribute * ptr = getNameDescriptor(); // needed, because we want to pass pointer-to-pointer-to-nameDescr
PercentageFill(PercentageUUID, valueBytes.getPointer(),
valueBytes.getNumValueBytes(), HeartRateValueBytes::MAX_VALUE_BYTES,
GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_EXTENDED_PROPERTIES,
&ptr, 1), /* are we sure about trailing comma here? */
// other relevant trailing code?
}
编辑以根据注释添加其他选项:
void updatePercentage(WhateverTypeValueBytesIs valueBytes, const char* name) {
GattAttribute nameDescr(BLE_UUID_DESCRIPTOR_CHAR_USER_DESC, (const uint8_t *) name, strlen(name));
GattAttribute * ptr = &nameDescr; // needed, because we want to pass pointer-to-pointer-to-nameDescr
PercentageFill(PercentageUUID, valueBytes.getPointer(),
valueBytes.getNumValueBytes(), HeartRateValueBytes::MAX_VALUE_BYTES,
GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_EXTENDED_PROPERTIES,
&ptr, 1), /* are we sure about trailing comma here? */
// other relevant trailing code?
}
或者另一种选择:琐碎,通过引用传入完全初始化的GattAttribute
:
void updatePercentage(WhateverTypeValueBytesIs valueBytes, GattAttribute & descr) {
GattAttribute * ptr = &descr; // needed, because we want to pass pointer-to-pointer-to-descr
PercentageFill(PercentageUUID, valueBytes.getPointer(),
valueBytes.getNumValueBytes(), HeartRateValueBytes::MAX_VALUE_BYTES,
GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_EXTENDED_PROPERTIES,
&ptr, 1), /* are we sure about trailing comma here? */
// other relevant trailing code?
}
你这样称呼:
void foo(WhateverTypeValueBytesIs valueBytes) {
GattAttribute nameDescr(BLE_UUID_DESCRIPTOR_CHAR_USER_DESC, (uint8_t *)"Percentage", strlen("Percentage"));
updatePercentage(valueBytes, nameDescr);
}
显然,除了使用引用之外,您还可以重新设计函数以获取指向GattAttribute
对象的指针(并使用它代替ptr
变量,就像示例中使用 ptr
变量一样(。
进一步补充:请注意,当您将valueBytes
传递给updatePercentage
时,您可能希望避免复制它,在这里您可能希望通过引用传递它。
- 使用QJsEngine在Qt中注册自定义类型
- 当我使用自定义类型创建动态数组时,即使使用字符串,它似乎也不起作用
- QtQuick - qml:28:错误:未知方法返回类型:自定义类型
- 如何使自定义类型在unordered_map中用作键
- Qt5 远程对象 + 自定义类型,但不在 POD 中
- 标准::原子中的自定义类型
- 如何使用自定义类型声明Arduino数组?
- 使用自定义访问者时具有自定义类型的提升变体失败(源自 boost::static_visitor)
- 您可以将binary_search应用于具有自定义类型的矢量吗?
- 在自定义类型图中重用 SWIG 映射
- 扩展自定义类型的spdlog
- 重载自定义类型的 std::to_string 和 std::to_chars?
- 自定义类型转换运算符在转发引用上调用时不起作用(当对象按值传递时有效)
- 初始化自定义类型构造函数的数组
- 如何使用 QListIterator 的声明自定义类型定义
- 向前删除标题文件中其他名称空间的自定义类型
- 如何为提升日志和自定义类型定义输出流运算符
- typedef 中的自定义类型为 Qt MetaType
- 无法专门化 std::hash 以unordered_map存储自定义类型
- 运算符/ STD :: Chrono ::持续时间和自定义类型与Clang