首页 > 解决方案 > Libwesockets.h:lws_write 的问题:C++ 字符串到 C 的转换并发送

问题描述

我正在使用 g++。

代码:

        std::string str = "{\"action\":3,\"data\":{\"account\":\"somehashgoeshear\",\"someint\":0,\"id\":1,\"moreint\":0,\"name\":\"demo\"}}";
        char *cstr = strdup(str.c_str());
        lwsl_notice("\n%s", cstr);
        return lws_write(wsi, (unsigned char*)cstr, strlen(cstr), LWS_WRITE_TEXT);

这也不起作用:

        std::string str = "{\"action\":3,\"data\":{\"account\":\"somehashgoeshear\",\"someint\":0,\"id\":1,\"moreint\":0,\"name\":\"demo\"}}";
        return lws_write(wsi, (unsigned char*)str.c_str(), strlen(str.c_str()), LWS_WRITE_TEXT);

但这工作正常(运行多次而没有错误):

        char cstr[96] = "{\"action\":3,\"data\":{\"account\":\"somehashgoeshear\",\"someint\":0,\"id\":1,\"moreint\":0,\"name\":\"demo\"}}";
        return lws_write(wsi, (unsigned char*)cstr, strlen(cstr), LWS_WRITE_TEXT);

也尝试使用创建字符串,malloc但这也不起作用:

        std::string str = "{\"action\":3,\"data\":{\"account\":\"somehashgoeshear\",\"someint\":0,\"id\":1,\"moreint\":0,\"name\":\"demo\"}}";
        char *cstr = (char *)malloc((str.length() + 1) * sizeof(char));
        strcpy(cstr, str.c_str());
        lwsl_notice("\n%s", cstr);
        return lws_write(wsi, (unsigned char*)cstr, strlen(cstr), LWS_WRITE_TEXT);

我可以多次运行此代码,但最终我收到此错误:( free(): invalid next size (fast) 发送数据后失败)

我也尝试了一些实验,LWS_PRE但是当我将它添加到字符串中时,它会在消息的开头添加几个符号,例如:a":

当我在发送数据后尝试时free(cstr),它立即失败并double free or corruption (out)出现错误。

lws 版本:1.7.1 操作系统:ubuntu x64

标签: c++stringmemory-managementlibwebsockets

解决方案


根据文档https://libwebsockets.org/lws-api-doc-master/html/group__sending-data.html#gafd5fdd285a0e25ba7e3e1051deec1001

重要通知!

使用 websocket 协议发送时

LWS_WRITE_TEXT、LWS_WRITE_BINARY、LWS_WRITE_CONTINUATION、LWS_WRITE_PING、LWS_WRITE_PONG、

或在 http/2 上发送,

在传递给 lws_write() 的缓冲区指针之前,发送缓冲区必须具有有效的 LWS_PRE 字节。

这意味着您必须为缓冲区分配额外的 LWS_PRE 字节,即

std::string str(LWS_PRE, ' '); //Allocate LWS_PRE bytes
str += "{\"action\":3,\"data\":{\"account\":\"somehashgoeshear\",\"someint\":0,\"id\":1,\"moreint\":0,\"name\":\"demo\"}}"
return lws_write(wsi, (unsigned char*)&str[LWS_PRE], str.size(), LWS_WRITE_TEXT);

使用 malloc

char* createMessage() {
  std::string str = "{\"action\":3,\"data\":{\"account\":\"somehashgoeshear\",\"someint\":0,\"id\":1,\"moreint\":0,\"name\":\"demo\"}}";
  char *cstr = (char *)malloc(LWS_PRE + (str.length() + 1) * sizeof(char));
  cstr += LWS_PRE;
  strcpy(cstr, str.c_str());
  lwsl_notice("\n%s", cstr);
  return cstr;
}
...
char* msg = createMessage();
lws_write(wsi, 
          (unsigned char*)msg, 
          strlen(msg) /* add 1 if receiver expects the null character*/, 
          LWS_WRITE_TEXT);
free(msg - LWS_PRE);

推荐阅读