Параметр функции работает от инициированного символа *, но не при преобразовании из символа [] - PullRequest
0 голосов
/ 03 мая 2019

У меня есть функция mqtt, которая подписывается на тему с помощью указателя char *. Поскольку я хочу подписаться только на свой идентификатор устройства, мне нужно динамически создать часть этого указателя. И я действительно не могу добиться успеха.

Я попытался создать массив [] динамически, а затем преобразовать весь массив в массив указателей *, но безуспешно. Это работает, только если я статически определяю указатель в виде char *.

Вот что хорошо работает:

char* topic="/mqtt_topic/myID/";
mqtt_subscribe(module_inst, topic, 0, SubscribeHandler);

Код ниже компилируется и выглядит нормально, функция также подписывается на тему, но не реагирует на данные, отправленные через mqtt. Строка также выглядит идентично примеру выше.

char topick []="/mqtt_topic/myID/";
char* topic=topick;
mqtt_subscribe(module_inst, topic, 0, SubscribeHandler);

Функция mqtt_subscribe выглядит следующим образом;

int mqtt_subscribe(struct mqtt_module *module, const char *topic, uint8_t qos, messageHandler msgHandler)
{
    int rc;

    rc = MQTTSubscribe(module->client, topic, qos, msgHandler);
    if(module->callback)
        module->callback(module, MQTT_CALLBACK_SUBSCRIBED, NULL);   

    return rc;
}

которая вызывает следующую функцию.

int MQTTSubscribe(MQTTClient* c, const char* topicFilter, enum QoS qos, messageHandler msgHandler)
{ 
    int rc = FAILURE;  
    Timer timer;
    int len = 0;
    MQTTString topic = MQTTString_initializer;
    int Qoss = (int) qos;
    topic.cstring = (char *)topicFilter;
#if defined(MQTT_TASK)
    MutexLock(&c->mutex);
#endif
    if (!c->isconnected)
        goto exit;

    TimerInit(&timer);
    TimerCountdownMS(&timer, c->command_timeout_ms);

    len = MQTTSerialize_subscribe(c->buf, c->buf_size, 0, getNextPacketId(c), 1, &topic, (int*)&Qoss);
 //   len = MQTTSerialize_subscribe(c->buf, c->buf_size, 0, getNextPacketId(c), 1, &topic, qos);
    if (len <= 0)
        goto exit;
    if ((rc = sendPacket(c, len, &timer)) != SUCCESS) // send the subscribe packet
        goto exit;             // there was a problem

    if (waitfor(c, SUBACK, &timer) == SUBACK)      // wait for suback 
    {
        int count = 0, grantedQoS = -1;
        unsigned short mypacketid;
        if (MQTTDeserialize_suback(&mypacketid, 1, &count, &grantedQoS, c->readbuf, c->readbuf_size) == 1)
            rc = grantedQoS; // 0, 1, 2 or 0x80 
        if (rc != 0x80)
        {
            int i;
            for (i = 0; i < MAX_MESSAGE_HANDLERS; ++i)
            {
                if (c->messageHandlers[i].topicFilter == 0)
                {
                    c->messageHandlers[i].topicFilter = topicFilter;
                    c->messageHandlers[i].fp = msgHandler;
                    rc = 0;
                    break;
                }
            }
        }
    }
    else 
        rc = FAILURE;

exit:
#if defined(MQTT_TASK)
    MutexUnlock(&c->mutex);
#endif
    return rc;
}

Это ожидаемые результаты? Есть ли способ решить эту проблему?

Ответы [ 2 ]

5 голосов
/ 03 мая 2019

Вы не показываете нам достаточно. Тем не менее, я предполагаю:

void myFunction(...)
{
    char topick []="/mqtt_topic/myID/";
    char* topic=topick;
    mqtt_subscribe(module_inst, topic, 0, SubscribeHandler);
    //...
}

или что-то в этом роде, т.е. topick объявлено внутри функции. Тогда это локальная переменная, которая перестает существовать, когда функция возвращается. Указатель на строку, которую вы передали, больше не указывает на допустимую строку.

С другой стороны:

char* topic="/mqtt_topic/myID/";
mqtt_subscribe(module_inst, topic, 0, SubscribeHandler);

Здесь topic указывает на литерал, и литерал остается существующим после возврата из функции. Таким образом, функция mqtt_.. получает допустимую строку, которая также существует после возврата вызывающей стороны.

0 голосов
/ 06 мая 2019

Ваш ответ полностью правильный, и я действительно объявляю массив локально.Объявление topick[64] глобально решило эту проблему.

Спасибо!

/ Микаэль

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...