Используйте виртуальную функцию в качестве обратного вызова для утешения подписчика темы ⇐ C++
-
Anonymous
Используйте виртуальную функцию в качестве обратного вызова для утешения подписчика темы
Я пытаюсь использовать Solace c API через классы C++.
В существующем проекте уже создана структура со ссылкой на базовый и производный классы, где производные виртуальные функции вызываются в соответствии с объектом, на который ссылаются во время выполнения.
Моя последняя задача — реализовать Solace как «подписку на тему», где я буду использовать ту же виртуальную функцию, что и метод обратного вызова существующего базового класса.
Для этого я разделил задачу на пошаговые и на первом этапе создал простой класс и попытался использовать функцию-член в качестве метода обратного вызова, но получаю сообщение об ошибке. Пожалуйста, предложите, какой подход мне следует использовать.
В приведенном ниже коде sessionMessageReceiveCallback — это метод обратного вызова. Каждый раз, когда сообщение публикуется в TestTopic, вызывается sessionMessageReceiveCallback.
Мне нужно вызвать виртуальный метод в строке кода ниже:
sessionFuncInfo.rxMsgInfo.callback_p = sessionMessageReceiveCallback; sessionFuncInfo.rxMsgInfo.user_p = NULL; Ниже приведен полный код:
os.h
#pragma один раз /** @example Intro/os.h */ /* * Методы абстрагирования, специфичные для ОС. * Авторские права принадлежат Solace Corporation, 2008–2019 гг. Все права защищены. */ #ifndef ___OS_H_ #define ___OS_H_ #ifdef __cplusplus внешний "С" { #endif #include #include #include #ifdef WIN32 #define _WIN32_WINNT 0x400 /* Для SignalObjectAndWait требуется Windows NT5 (2000, XP, 2003) */ #include #include #include #define SLEEP(sec) Спящий режим ( (sec) * 1000 ) #define strcasecmp (_stricmp) #define strncasecmp (_strnicmp) #еще #include #define SLEEP(sec) сон ( (sec) ) #endif #ifdef __cplusplus } #endif #endif TopicSubscr.h
#include "os.h" #include "solclient/solClient.h" #include "solclient/solClientMsg.h" класс TopicSubscr { частный : solClient_rxMsgCallback_returnCode_t sessionMessageReceiveCallback(solClient_opaqueSession_pt opaqueSession_p, solClient_opaqueMsg_pt msg_p, void* user_p); общественность: solClient_opaqueSession_pt session_p; статический интервал msgCount; явный TopicSubscr(); ~TopicSubscr(); }; TopicSubscr.cpp
#include "TopicSubscr.h" /* Количество сообщений */ статический интервал msgCount = 0; /*************************************************** **************************** * sessionMessageReceiveCallback * * Обратный вызов сообщения вызывается для каждого прямого сообщения, полученного * сессия. В этом примере сообщение выводится на экран. **************************************************** ***************************/ solClient_rxMsgCallback_returnCode_t TopicSubscr::sessionMessageReceiveCallback (solClient_opaqueSession_pt opaqueSession_p, solClient_opaqueMsg_pt msg_p, void* user_p) { printf("Получено сообщение:\n"); solClient_msg_dump (msg_p, NULL, 0); printf("\n"); //msgCount++; вернуть SOLCLIENT_CALLBACK_OK; } /*************************************************** **************************** * sessionEventCallback * * Функция обратного вызова события обязательна для создания сеанса. **************************************************** ***************************/ пустота sessionEventCallback(solClient_opaqueSession_pt opaqueSession_p, solClient_session_eventCallbackInfo_pt eventInfo_p, void* user_p) { } TopicSubscr::TopicSubscr() { /* Контекст */ solClient_opaqueContext_pt context_p; solClient_context_createFuncInfo_t contextFuncInfo = SOLCLIENT_CONTEXT_CREATEFUNC_INITIALIZER; /* Сеанс */ solClient_session_createFuncInfo_t sessionFuncInfo = SOLCLIENT_SESSION_CREATEFUNC_INITIALIZER; /* Свойства сеанса */ const char* sessionProps[25] = {0,}; int propIndex = 0; /*************************************************** ************************ * Инициализируйте API (и настройте уровень ведения журнала). **************************************************** ***********************/ /* solClient необходимо инициализировать перед любыми другими вызовами API. */ solClient_initialize (SOLCLIENT_LOG_DEFAULT_FILTER, NULL); printf("Инициализация TopicSubscriber...\n"); /*************************************************** ************************ * Создать контекст **************************************************** ***********************/ /* * Создайте контекст и укажите, что будет создан поток контекста. * автоматически вместо того, чтобы приложение создавало свой собственный * Контекстная ветка. */ solClient_context_create(SOLCLIENT_CONTEXT_PROPS_DEFAULT_WITH_CREATE_THREAD, &context_p, &contextFuncInfo, sizeof(contextFuncInfo)); /*************************************************** ************************ * Создать и подключить сеанс **************************************************** ***********************/ /* Настраиваем информацию о функции сеанса. */ sessionFuncInfo.rxMsgInfo.callback_p = sessionMessageReceiveCallback; sessionFuncInfo.rxMsgInfo.user_p = NULL; sessionFuncInfo.eventInfo.callback_p = sessionEventCallback; // C:\SolaceCCode\solace-samples-c-master\build\intro\win\VS2008\TopicSubscriber\TopicSubscr.cpp(76,73): ошибка C3867: 'TopicSubscr::sessionMessageReceiveCallback': нет -стандартный синтаксис; используйте '&', чтобы создать указатель на член 2> C:\SolaceCCode\solace-samples-c-master\build\intro\win\VS2008\TopicSubscriber\TopicSubscr.cpp(76,73): ошибка C2440: '=': невозможно преобразовать из 'solClient_rxMsgCallback_returnCode_t (__thiscall TopicSubscr: :* )(solClient_opaqueSession_pt,solClient_opaqueMsg_pt,void *)» до «solClient_session_rxMsgCallbackFunc_t» 2> C:\SolaceCCode\solace-samples-c-master\build\intro\win\VS2008\TopicSubscriber\TopicSubscr.cpp(76,44): сообщение: нет контекста, в котором возможно это преобразование Ссылка на solclient.h:
Ссылка на solClientMsg.h:
Пример, который я использовал для справки:
Я пытаюсь использовать Solace c API через классы C++.
В существующем проекте уже создана структура со ссылкой на базовый и производный классы, где производные виртуальные функции вызываются в соответствии с объектом, на который ссылаются во время выполнения.
Моя последняя задача — реализовать Solace как «подписку на тему», где я буду использовать ту же виртуальную функцию, что и метод обратного вызова существующего базового класса.
Для этого я разделил задачу на пошаговые и на первом этапе создал простой класс и попытался использовать функцию-член в качестве метода обратного вызова, но получаю сообщение об ошибке. Пожалуйста, предложите, какой подход мне следует использовать.
В приведенном ниже коде sessionMessageReceiveCallback — это метод обратного вызова. Каждый раз, когда сообщение публикуется в TestTopic, вызывается sessionMessageReceiveCallback.
Мне нужно вызвать виртуальный метод в строке кода ниже:
sessionFuncInfo.rxMsgInfo.callback_p = sessionMessageReceiveCallback; sessionFuncInfo.rxMsgInfo.user_p = NULL; Ниже приведен полный код:
os.h
#pragma один раз /** @example Intro/os.h */ /* * Методы абстрагирования, специфичные для ОС. * Авторские права принадлежат Solace Corporation, 2008–2019 гг. Все права защищены. */ #ifndef ___OS_H_ #define ___OS_H_ #ifdef __cplusplus внешний "С" { #endif #include #include #include #ifdef WIN32 #define _WIN32_WINNT 0x400 /* Для SignalObjectAndWait требуется Windows NT5 (2000, XP, 2003) */ #include #include #include #define SLEEP(sec) Спящий режим ( (sec) * 1000 ) #define strcasecmp (_stricmp) #define strncasecmp (_strnicmp) #еще #include #define SLEEP(sec) сон ( (sec) ) #endif #ifdef __cplusplus } #endif #endif TopicSubscr.h
#include "os.h" #include "solclient/solClient.h" #include "solclient/solClientMsg.h" класс TopicSubscr { частный : solClient_rxMsgCallback_returnCode_t sessionMessageReceiveCallback(solClient_opaqueSession_pt opaqueSession_p, solClient_opaqueMsg_pt msg_p, void* user_p); общественность: solClient_opaqueSession_pt session_p; статический интервал msgCount; явный TopicSubscr(); ~TopicSubscr(); }; TopicSubscr.cpp
#include "TopicSubscr.h" /* Количество сообщений */ статический интервал msgCount = 0; /*************************************************** **************************** * sessionMessageReceiveCallback * * Обратный вызов сообщения вызывается для каждого прямого сообщения, полученного * сессия. В этом примере сообщение выводится на экран. **************************************************** ***************************/ solClient_rxMsgCallback_returnCode_t TopicSubscr::sessionMessageReceiveCallback (solClient_opaqueSession_pt opaqueSession_p, solClient_opaqueMsg_pt msg_p, void* user_p) { printf("Получено сообщение:\n"); solClient_msg_dump (msg_p, NULL, 0); printf("\n"); //msgCount++; вернуть SOLCLIENT_CALLBACK_OK; } /*************************************************** **************************** * sessionEventCallback * * Функция обратного вызова события обязательна для создания сеанса. **************************************************** ***************************/ пустота sessionEventCallback(solClient_opaqueSession_pt opaqueSession_p, solClient_session_eventCallbackInfo_pt eventInfo_p, void* user_p) { } TopicSubscr::TopicSubscr() { /* Контекст */ solClient_opaqueContext_pt context_p; solClient_context_createFuncInfo_t contextFuncInfo = SOLCLIENT_CONTEXT_CREATEFUNC_INITIALIZER; /* Сеанс */ solClient_session_createFuncInfo_t sessionFuncInfo = SOLCLIENT_SESSION_CREATEFUNC_INITIALIZER; /* Свойства сеанса */ const char* sessionProps[25] = {0,}; int propIndex = 0; /*************************************************** ************************ * Инициализируйте API (и настройте уровень ведения журнала). **************************************************** ***********************/ /* solClient необходимо инициализировать перед любыми другими вызовами API. */ solClient_initialize (SOLCLIENT_LOG_DEFAULT_FILTER, NULL); printf("Инициализация TopicSubscriber...\n"); /*************************************************** ************************ * Создать контекст **************************************************** ***********************/ /* * Создайте контекст и укажите, что будет создан поток контекста. * автоматически вместо того, чтобы приложение создавало свой собственный * Контекстная ветка. */ solClient_context_create(SOLCLIENT_CONTEXT_PROPS_DEFAULT_WITH_CREATE_THREAD, &context_p, &contextFuncInfo, sizeof(contextFuncInfo)); /*************************************************** ************************ * Создать и подключить сеанс **************************************************** ***********************/ /* Настраиваем информацию о функции сеанса. */ sessionFuncInfo.rxMsgInfo.callback_p = sessionMessageReceiveCallback; sessionFuncInfo.rxMsgInfo.user_p = NULL; sessionFuncInfo.eventInfo.callback_p = sessionEventCallback; // C:\SolaceCCode\solace-samples-c-master\build\intro\win\VS2008\TopicSubscriber\TopicSubscr.cpp(76,73): ошибка C3867: 'TopicSubscr::sessionMessageReceiveCallback': нет -стандартный синтаксис; используйте '&', чтобы создать указатель на член 2> C:\SolaceCCode\solace-samples-c-master\build\intro\win\VS2008\TopicSubscriber\TopicSubscr.cpp(76,73): ошибка C2440: '=': невозможно преобразовать из 'solClient_rxMsgCallback_returnCode_t (__thiscall TopicSubscr: :* )(solClient_opaqueSession_pt,solClient_opaqueMsg_pt,void *)» до «solClient_session_rxMsgCallbackFunc_t» 2> C:\SolaceCCode\solace-samples-c-master\build\intro\win\VS2008\TopicSubscriber\TopicSubscr.cpp(76,44): сообщение: нет контекста, в котором возможно это преобразование Ссылка на solclient.h:
Ссылка на solClientMsg.h:
Пример, который я использовал для справки:
Мобильная версия