Запутался в этой строке кода, которая предназначена для использования в качестве класса в указатель void - PullRequest
0 голосов
/ 31 мая 2019

Я учился отправлять данные в программу с именем FogLAMP https://github.com/foglamp/, и данные, которые я хочу отправить, являются асинхронными.Мой вопрос не о самой кодовой базе foglamp, а о приведенной ниже строке кода.

Я в целом понимаю, что делает код.Но я не знаю точную механику в памяти или синтаксис в этом отношении.

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

Это поглощение кода, поэтому, поскольку программа запускает два асинхронных потока (процесс сбора и отправки данных (pid (1)) и фактический код, настроенный как процесс демона (pid (2))), она предназначена длявыделить указатель void (void * m_data), который в конечном итоге будет заполнен объектом чтения, который должен быть отправлен в облако через процесс (1).Это чтение производится, однако, в процессе (2).Поэтому я считаю, что процесс (2) создает объект чтения в памяти, чтобы процесс (1) мог получить доступ к этим данным.Я включил соответствующий код ниже, чтобы следовать пути выполнения).

void    (*m_ingest)(void *, Reading);

Я нигде не видел этот синтаксис, и я не могу описать это в Google, поэтому я не совсем уверен, что это означает в C ++.

Я извиняюсь, что не могу предоставить гораздо больше информации.Я не был уверен, как это описать, вроде как приведение к типу m_ingest (который не является глобальной переменной или typedef).

Я просматриваю этот код, потому что хотел бы внедрить то же самое в свой собственный плагин противотуманной фары с использованием Robotic Operating Systems (ROS) в качестве многопоточной асинхронной передачи данных в противотуманную фару.

Thisэто рассматриваемый код

void    (*m_ingest)(void *, Reading);
void    *m_data;

Эти две переменные появляются в следующих функциях (не совсем уверен, что означает (* cb) (void *, Reading).

void OPCUA::registerIngest(void *data, void (*cb)(void *, Reading))
{
    m_ingest = cb;
    m_data = data;
}

/**
 * Called when a data changed event is received. This calls back to the south service
 * and adds the points to the readings queue to send.
 *
 * @param points    The points in the reading we must create
 */
void OPCUA::ingest(vector<Datapoint *>  points)
{
string asset = m_asset + points[0]->getName();

    (*m_ingest)(m_data, Reading(asset, points));
}

комментарий очень полезен, утверждая, что ingest помещает массив указателей Datapoint в очередь для отправки в foglamp. Имеет смысл, что это делает, но я хотел бы получить более надежное объяснение того, что на самом деле происходит в памяти.

Исходный код в вопросе находится в хранилище https://github.com/foglamp/foglamp-south-opcua

Вот исходный код https://github.com/foglamp/foglamp-south-opcua/blob/develop/opcua.cpp

Вот заголовочный файл https://github.com/foglamp/foglamp-south-opcua/blob/develop/include/opcua.h

1 Ответ

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

Довольно простой с ++ здесь. Благодаря @ 1201ProgramAlarm. Это просто указатель на функцию. Я прочитал краткое руководство здесь https://www.cprogramming.com/tutorial/function-pointers.html. Но теперь я вижу, что (* cb) - это указатель на функцию, передаваемый через register_ingest для назначения m_ingest той же функции, что и (* cb). Таким образом, когда foglamp нужны данные, он обращается к ним через m_ingest. Эта функция очень помогает

void plugin_register_ingest(PLUGIN_HANDLE *handle, INGEST_CB cb, void *data)
{
OPCUA *opcua = (OPCUA *)handle;

    if (!handle)
        throw new exception();
    opcua->registerIngest(data, cb);
}

Таким образом, INGEST_CB - это глобальная функция обратного вызова, определенная в некотором заголовочном файле foglamp, которая затем назначается тому же адресу, что и m_ingest.

Унизительно изучать что-то новое в C ++. Я никогда не видел, чтобы указатели на функции проходили таким образом, только адреса функций (т.е. через std :: bind (& func, param)).

...