У меня есть небольшой сервер веб-сокетов, созданный с помощью libwebsockets, и мне нужно получить строку, проблема в том, что полученные данные * недействительны, но у меня возникают проблемы при преобразовании их в строку.
static int my_protocol_callback(struct libwebsocket_context *context,
struct libwebsocket *wsi,
enum libwebsocket_callback_reasons reason,
void *user, void *in, size_t len)
{
int n, m;
unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 512 +
LWS_SEND_BUFFER_POST_PADDING];
unsigned char *p = &buf[LWS_SEND_BUFFER_PRE_PADDING];switch (reason) {
case LWS_CALLBACK_ESTABLISHED:
printf("New Connection\n");
break;
case LWS_CALLBACK_SERVER_WRITEABLE:
break;
case LWS_CALLBACK_RECEIVE:
webcmd = static_cast<std::string*>(in);
break;
case LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION:
break;
default:
break;
}
return 0;
}
под LWS CALLBACK RECEIVE
случай, данные *in
и я произнес это static_cast<std::string*>(in);
хранится в строке webcmd.
проблема в том, что результатом является указатель на символ, вместо этого мне нужен настоящий символ, потому что затем мне нужно разделить строку.
что ты думаешь об этом?
РЕДАКТИРОВАТЬ: решена проблема.
Под case LWS_CALLBACK_RECEIVE:
tmpcmd = reinterpret_cast <char*>(in);
strcpy(webcmd , tmpcmd );
webcmd это массив символов
и tmpcmd является указателем на символ
спасибо за все: D
Ты не можешь просто static_cast
на что угодно и надеюсь, что это сработает. К сожалению, вы можете без предупреждения разыграть void*
на что угодно.
static_cast
, лайк reinterpret_cast
просто изменяет тип во время компиляции без каких-либо проверок того, действительно ли то, на что указывает указатель, представляет тип, к которому вы его приводите.
В этом случае std :: string является сложным типом с несколькими переменными-членами и представлением в памяти. И если вы не прошли точно такой же тип, у вас будут катастрофические результаты.
Было бы намного лучше перейти в фактический тип, а не void*
, но я не знаю, возможно ли это с тем, что вы делаете.
Если вам действительно нужна строка, то вам нужно использовать один из std::string
конструкторы.
Как это:
case LWS_CALLBACK_RECEIVE:
std::string command(static_cast<char*>(in));
webcmd = command; //I don't know what webcmd is.
break;
«в» должен быть некоторый массив символов, вы должны сделать что-то вроде этого:
char * buf = new char[DATA_SIZE];
а затем память скопировать данные в него в виде массива символов (или BYTE).
Однажды что-то было брошено на void*
вся информация типа была потеряна.
Необходимо выполнить поиск в коде / документации, которая устанавливает функцию обратного вызова, и преобразовать обратно в тип данных экземпляра, который был первоначально приведен к void*
, Вполне может быть std::string*
, но могут быть и другие типы, такие как char*
, Затем, чтобы сделать ваш код действительно понятным, используйте reinterpret_cast
:
whateverthetypeis* = reinterpret_cast<whateverthetypeis*>(in);
В наши дни обратные вызовы могут быть смоделированы как функторы или с помощью шаблонов. Тогда информация о типе сохраняется. Механизм, который вы используете в настоящее время, — это возврат к старым временам C, когда void*
был использован в качестве универсального типа.
Что касается желания истинного char
; Вы не получите это. char
это просто число от -128 до +127. Однако символ * (то есть символ указатель) используется C и C ++ для моделирования последовательности ненулевых символов, начиная с области памяти, обозначенной char*
то есть строка.
Если окажется, что in
это char*
, то вы можете построить std::string
с in
в качестве аргумента конструктора и разделите std :: string на досуге.