Значение по умолчанию для обратного вызова возможно в C? - PullRequest
1 голос
/ 14 апреля 2020

У меня проблема, код лучше слов.


static void message_cb(int friend_number, char const *message) {
    // ...

    // I need to access instance (from `init`) here.

    // I can't modify the parameters of message_cb unfortunately...


    // ...
} 

// There will be a lots of different `instance`,
// so I can't really use a global variable...
static void init(Chat *instance)
{
    // ...

    callback_message(message_cb);

    // ...
}

Короче говоря, мне нужно сделать что-то вроде этого, но в C: (например, генерация функции в зависимости от instance параметры)

static void init(Chat *instance)
{
    // ...

    callback_message(void (int friend_number, char const *message) {
        // Here I can access `instance`
    });

    // ...
}

Извините за мой короткий и, вероятно, плохой английский sh, это не мой родной язык ...

Заранее спасибо

1 Ответ

0 голосов
/ 14 апреля 2020

Учитывая, что вы не можете изменить параметры сообщения cb к сожалению один из способов инициализации обратного вызова с настраиваемым значением - создать переменную extern, возможно в файле .h, обеспечивающем видимость для любого файла .c, которому требуется его текущее значение или адрес (в зависимости от того, как определен экземпляр ):

.h файл

//declare project global here
extern <type><name>;

file1. c

//define project global here
<type><name> = somevalue;  

Примечание: Предшествующая идея была предложена до того, как OP-многопоточная среда была вероятна в ответ на комментарии в первоначально размещенный вопрос.

В ответ на комментарий о многопоточности ...

Если есть какой-либо глобальный объект (сообщение, значение, некоторый другой объект) должен использоваться в многопоточной среде, тогда он должен быть защищен таким образом, чтобы контролировать доступ к его значению и изменять его путем создания, например, одним из двух следующих способов:

  • использовать структуру блокировки (например, мьютекс) для защиты разделяемой переменной с использованием критической секции .
  • использует атоми c для доступа к объекту, новый стандарт C, C11 поддерживает эту конструкцию.

... или использовать их таким образом, чтобы окружить их критическими секциями защищенного кода, как, например, можно сделать с помощью блокировки.

Есть много учебных пособий по этой теме c, например. this .

Вот быстрый и грязный пример концепции использования безопасности потоков с помощью блокировки:

// Your function modified with pseudo code for concept illustration

//static void init(Chat *instance)
static bool init(Chat *instance)
{
    bool status = FALSE;
    struct ts_lock lock = {0};
    get_lock(&lock);

    if(lock.granted)
    {
        //populate message from instance here
        // <some code to populate 'message'>
        callback_message(void (int friend_number, char const *message) {
        // Here I can access `instance`

        status = TRUE;
        release_lock(lock);
    }

    return status;

    // ...
}
...