Как управлять принципами C ++ с C-совместимыми библиотеками и API - PullRequest
0 голосов
/ 23 мая 2019

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

Первая проблема, с которой я столкнулся, заключается в том, что, например, в OpenSSL есть функции, которые принимают char* в качестве аргументов.

В C ++ не рекомендуется использовать char*. Я читал, что некоторые люди рекомендуют std::string или std::vector<char>.

Но, например, BIO_read (которая записывает данные в char*), функция в OpenSSL принимает char*. std::string имеет функцию c_str(), но возвращает const char*. Я знаю, что могу разыграть const, используя const_cast, но это не очень хорошая идея, потому что это не тот способ, которым нужно менять строку.

Что такое «C ++ решение» этой проблемы? Я хочу использовать принципы RAII и OOP. Единственное решение, которое я мог придумать, - это создать класс, который бы принимал размер памяти в качестве аргумента в конструкторе и имел что-то вроде char* _buf = new char[size] и освобождал память в деструкторе. Это лучшее решение в этой ситуации?

Или куда мне поместить данные, полученные из сокета, используя recv, когда я не знаю их размер? В C я бы выделил память, используя malloc, и записал ее там. Но как я могу сделать это в стиле C ++? Создайте класс, который я упомянул выше, и используйте его вместо malloc?

1 Ответ

7 голосов
/ 23 мая 2019

std::string также имеет .data(), который вы должны использовать для этой задачи (по крайней мере, в современном C ++, где строковые данные гарантированно являются смежными).

Кроме этого, да, возможно, вам придется сделатьнекоторые компромиссы из лучших практик C ++ при работе с C API.Это особенно заметно с обратными вызовами, к которым нельзя передать захват лямбда-функций или указателей на функции-члены без некоторого количества уродливых механизмов.

Некоторые библиотеки C дополняются оболочками C ++, написанными либо исходной библиотекойавтор или сторонний разработчик (например, MySQL ++, curlpp) - это означает, что уродливые механизмы созданы для вас, и вам не нужно об этом беспокоиться.

Ваше решение _buf не страшно, но std::vector<char> тогда может быть лучше или std::unique_ptr<char[]> (хотя, опять же, учтите, что std::string вполне может подойти для ваших нужд в конце концов.)

Для recv, то естьДругое дело, и это не то, что действительно относится к принципам проектирования C ++.Вы уже должны учитывать, что вы не знаете, сколько байтов доступно для чтения, поэтому вам уже нужно многократно читать в небольшой буфер и обрабатывать данные по мере их поступления.Таким образом, вы можете использовать для этого автоматическое хранилище char buf[1024] - там никогда не было необходимости в malloc, а сейчас его еще нет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...