In der Funktion unten habe ich http_client
von cpprestsdk (https://github.com/Microsoft/cpprestsdk) verwendet, um HTTP-Anfragen an eine Netzwerkkamera zu machen. Die folgende Funktion ist wahrscheinlich ein Callback, der von der lcm-Bibliothek (http://lcm-proj.github.io/) aufgerufen wird, wenn eine bestimmte Anfrage gestellt wird.shared_ptr vs. neuer Operator: welcher zu verwenden
Ich hatte Probleme mit der Linie 11. Ich zuvor den neuen Operator wurde:
auto init_session_response = new init_session_response_t;
die Zeiger zu erstellen und manuell einfach gelöscht werden, bevor die Funktion verlassen. Aber ich habe Ausnahme eine Zugriffsverletzung beim Versuch, das init_session_response
Objekt in der pplx Aufgabe Fortsetzung 49. in Zeile
init_session_response->status_code =
ptz_camera::status_codes_t::OK;
Dieses Problem ging weg zu ändern, wenn ich mit std :: shared_ptr gestartet. Kann mir jemand erklären, warum die Verwendung von shared_ptr das Problem gelöst hat? Soll der http_client * auch mit std :: shared_ptr erstellt werden?
1 void lcm_handler::on_init_session_req(const lcm::ReceiveBuffer* rbuff,
2 const std::string& channel,
3 const ptz_camera::init_session_request_t* req)
4 {
5 std::cout << "Received init session req on channel: " << channel <<
6 "; Camera: " << req->ip_address << std::endl;
7
8 auto ip_address = req->ip_address;
9
10 // Note use of std::shared_ptr
11 auto init_session_response = make_shared<ptz_camera::init_session_response_t>();
12
13 auto key_position = this->ip_client_map.find(ip_address);
14 if (key_position == ip_client_map.end())
15 {
16 std::cout << "Creating a new client for the ip: "
17 << req->ip_address << endl;
18
19 wstring username = this->convert_to_wstring(req->username);
20 wstring password = this->convert_to_wstring(req->password);
21
22 wstring main_uri = L"http://" + convert_to_wstring(ip_address);
23 auto config = http_client_config();
24 auto login = credentials(username, password);
25 config.set_credentials(login);
26 config.set_timeout(std::chrono::milliseconds(500));
27
28 http_client* client = new http_client(main_uri, config);
29 std::cout << "Client created...\n";
30
31 uri_builder uri = uri_builder(U("/") + uri_constants::stw_cgi).
32 append_path(uri_constants::attributes_cgi).append_path(uri_constants::attributes);
33
34 auto request = uri.to_string();
35
36 client->request(methods::GET, request)
37 .then([this, ip_address, client, init_session_response]
38 (pplx::task<http_response> request_task) -> pplx::task<wstring>
39 {
40 try
41 {
42 auto response = request_task.get();
43 if (response.status_code() == status_codes::OK)
44 {
45 std::cout << "Saving client...";
46 this->ip_client_map[ip_address] = client;
47 std::cout << "success.\n";
48
49 init_session_response->status_code =
50 ptz_camera::status_codes_t::OK;
51 }
52
53 else
54 {
55 cout << "GET request to client failed! HTTP Error: "
56 << response.status_code() << std::endl;
57
58 init_session_response->status_code =
59 ptz_camera::status_codes_t::ERR;
60 }
61
62 return response.extract_string();
63 }
64
65 catch (const exception& e)
66 {
67 cout << "Caught exception: " << e.what() << endl;
68 return create_task([e, this]() -> wstring
69 {
70 return convert_to_wstring(e.what());
71 });
72 }
73
74 })
75 .then([init_session_response, this](wstring response)
76 {
77 string n = this->convert_to_string(response);
78 init_session_response->response_message = n;
79 });
80 }
81
82
83 else
84 {
85 string message = "Client for ip: " + req->ip_address + " already exists\n";
86 cout << message << endl;
87 init_session_response->response_message = message;
88 init_session_response->status_code = ptz_camera::status_codes_t::OK;
89 }
90
91 this->lcm->publish(ptz_camera_channels::init_session_res_channel,
92 init_session_response.get());
93}
'shared_ptr' und' new' schließen sich nicht gegenseitig aus, obwohl es eine gute Vorgehensweise ist, sie im Allgemeinen mit 'make_shared' zu behalten. – chris
bedenken Sie mit "löschen" die Folgen sind sofort (mehr oder weniger) - die Objekte aufhören zu gelten. Dies ist relevant, wenn Sie einen Callback/Task einrichten, der auf den Wert nach "delete" verweisen muss, der außerhalb der Prozedur liegen könnte, die das Objekt zuweist (z. B. ein Lambda, das die Adresse als erfassten Wert verwendet). –
Es ist wahrscheinlich besser, den Code zu posten, der * nicht funktioniert * wenn Sie möchten, dass wir herausfinden, warum es nicht funktioniert. – Galik