Проблемы с преобразованием константного массива char в беззнаковый указатель char

Я работал над проектом, и мальчик, о, мальчик, у меня болит голова от этого. Я использую сетевую библиотеку под названием «ENET«и я пытаюсь назначить клиента, который подключает информацию. Используя учебник на сайте, я использую: server.event.packet->data = "client info"; Однако enet жалуется, что строка не является «беззнаковым символом *». Вот журнал сборки (используя clang ++ для компиляции):

./network.h:9:14: warning: in-class initialization of non-static data member accepted as a C++11 extension
[-Wc++11-extensions] int clients = 0;
^
main.cpp:142:28: error: assigning to 'enet_uint8 *' (aka 'unsigned char *') from incompatible type
'const char [12]';
server.event.packet->data = "client info";
^ ~~~~~~~~~~~~~

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

main.cpp:

#include <iostream>
#include <string>
#include <sstream>
#include <istream>
#include <cstring>
#include <cstdio>
#include <unistd.h>
#include <stdio.h>
#include "network.h"#include "clients.h"#include "config.h"
void runCommand(std::string command);
int startNetwork();
void shutdownNetwork();
void addClientRecord();
std::string getUsername();

std::string username;

bool manualInput = false;
bool debug = true;

int iPeerCount = 0;

Server server;

int main(int argc, char ** argv){
std::string currentCommand;

if(manualInput==true){
std::cout << "Please type a command: ";
std::getline(std::cin,currentCommand);
if(debug == true){
std::cout << currentCommand << std::endl;
}
runCommand(currentCommand);
}

startNetwork();

atexit(shutdownNetwork);

return 0;
}

int startNetwork(){
if (enet_initialize () != 0){
std::cout << "\nAn error has occured while initializing ENet.\n";
return EXIT_FAILURE;
}
server.startServer();
return 1;
}

void shutdownNetwork(){
enet_deinitialize();
}

int Server::startServer(){

//  server.serverOne = enet_host_create (& server.address, 32, 2, 0, 0);

//  if(CUSTOM_HOST == true){
//      enet_address_set_host(&address, HOST);
//  } else {
server.address.host = ENET_HOST_ANY;
//  }
server.address.port = PORT;

server.serverOne = enet_host_create( & server.address, 32, 2, 0, 0);

if(debug==true){
printf("[NETWORK] Host: %x \n[NETWORK] Port: %u\n", server.address.host, address.port);
}

if(server.serverOne==NULL){
std::cout << "\nAn error has occured while starting the ENet server.\n";
exit (EXIT_FAILURE);
}

monitor();
return 1;
}void Server::monitor(){
int clients = 0;
if(debug==true){
printf( "[NETWORK] Waiting for commands...\n" );
}
printf("[NETWORK] Server online, awaiting commands and/or connections...\n");
scan_network:
while(enet_host_service (serverOne, & event, 1000) > 0){
switch(event.type){
case ENET_EVENT_TYPE_CONNECT:
clients++;
printf("[INFO] New connection from: %x:%u.\n", event.peer -> address.host, event.peer -> address.port);
addClientRecord();
/*          for(int x=0;x<32;x++){
if(clients[x].name != ""){ }
else{
clients[x].name = "full";
}
}*/
break;
case ENET_EVENT_TYPE_RECEIVE:
if(debug==true){ printf("A packet of length %lu containing %s was received from %s on channel %u.\n", event.packet -> dataLength, event.packet -> data, event.peer -> data, event.channelID); }
runCommand(reinterpret_cast<const char*>(event.packet -> data));
enet_packet_destroy(event.packet);
/*              printf("Disconnect client %s ? ", event.peer -> data);
gets(buffer);
std::cout<<buffer<<std::endl;
if(buffer=="yes"){
enet_peer_disconnect(event.peer, 0);
}*/   //Do not use until fixed or spam!
break;
case ENET_EVENT_TYPE_DISCONNECT:
clients--;
printf("%s disconnected.\n", event.peer -> data);
event.peer -> data = NULL;
case ENET_EVENT_TYPE_NONE:
break;
}
}
goto scan_network;
}

void runCommand(std::string command){
if((command == "disconnect") || (command == "Disconnect") || (command=="DISCONNECT")){
enet_peer_disconnect(server.event.peer,0);
printf("[INFO] Client %s issued the disconnect command.\n", server.event.peer -> data);
}
}

std::string getUsername(){
return username;
}

void addClientRecord(){
std::string bufferName = ("client " + server.clients);
server.event.packet->data = "client info";
}

Network.h:

#include <enet/enet.h>

class Server {
public:
ENetAddress address;
ENetHost * serverOne;
ENetEvent event;

int clients = 0;

int startServer();
void monitor();
};

Любые идеи и помощь очень ценятся. Ура!

0

Решение

Насколько я вижу server это структура типа Server, его поле event является ENetEventи его поле packet имеет тип _ENetPacket* и его полевые данные являются unsigned char*, Итак, что происходит: вы создаете строку в стеке, а затем назначаете адрес первого элемента data поле глобального объекта, затем вы покидаете функцию, и указатель остается живым, в то время как сохраненные там данные больше не доступны. Вот почему вы получаете segfault при использовании правильного Typecast для unsigned char*,
Поэтому вы должны сделать следующее:

void addClientRecord()
{
std::string bufferName = ("client " + server.clients);
char* clientName = "client info";
// Allocate mem
char* data = new unsigned char[strlen(clientName)];
// Copy string there
strcpy(data, clientName);
// Store pointer
server.event.packet->data = (unsigned char*)data;
}

и не забывайте прояснить, что выделено мем. Это для вас всегда следует проверять, если server.event.packet->data содержит значение, отличное от nullptr, и, если оно есть, — удалить и только потом назначить. И вы должны предоставить деструктор для Server где он удалит эту строку, если какой-либо подарок и конструктор запишут туда nullptr при запуске, чтобы вы не удалили какой-либо мусорный адрес, что наверняка приведет к сбою. Но прежде всего нужно выяснить, _ENetPacket или же ENetEvent классы предоставляют любую функциональность для data упомянутое выше. Вот как работают cstrings.

Постскриптум Там должен быть флаг компилятора, который будет переключаться char быть неподписанным по умолчанию.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]