Thiago
Thiago

Reputation: 3

C++ libcurl returning null?

I'm new to c++ and need to implement a request in a class. But the answer I'm getting is coming null. From what I've been researching, it's a problem with the static WriteCallback function. But I can't solve the problem, how can I solve it?

class AbstractInstanceParser
    {

    public:
        static size_t WriteCallback(char *contents, size_t size, size_t nmemb, char *buffer_in)
        {
            ((std::string *)buffer_in)->append((char *)contents, size * nmemb);
            return size * nmemb;
        }

        bool parse()
        {

            CURL *curl = curl_easy_init();
            CURLcode res;
            Json::Value json;
            Json::Reader reader;
            double distance;
            std::string readBuffer;
            auto ok = parse_impl();
            if (!ok)
            {
                return ok;
            }

            auto matrix_size = static_cast<int>(demands.size());

            costs_matrix.resize(matrix_size, matrix_size);

            for (auto i = 0; i < matrix_size - 1; i++)
            {

                costs_matrix.at(i, i, 0.0f);

                for (auto j = i + 1; j < matrix_size; j++)
                {

                    if (curl)
                    {
                        curl_easy_setopt(curl, CURLOPT_URL, "http://localhost:5000/route/v1/driving/" + std::to_string(x_coordinates[i]) + "," + std::to_string(y_coordinates[i]) + ";" + std::to_string(x_coordinates[j]) + "," + std::to_string(y_coordinates[j]) + "?annotations=distance");
                        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
                        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);

                        res = curl_easy_perform(curl);

                        reader.parse(readBuffer, json);
                        distance = json["routes"][0]["distance"].asFloat();
                        std::cout << distance << std::endl;
                    }
                    costs_matrix.at(i, j, distance);

                    if constexpr (round_costs)
                    {
                        costs_matrix.at(i, j, std::round(costs_matrix.at(i, j)));
                    }

                    costs_matrix.at(j, i, costs_matrix.at(i, j));
                }
            }

            curl_easy_cleanup(curl);

            ...
            ...
            ...

I ran libcurl this way outside of a class and it worked fine, but inside a class, it doesn't work.

Upvotes: 0

Views: 253

Answers (1)

3CxEZiVlQ
3CxEZiVlQ

Reputation: 38332

std::string value is not allowed to be passed to curl_easy_setopt(curl, CURLOPT_URL, ...);

What you do (I changed your very long hard to read line):

const std::string url = "http://localhost:5000/route/v1/driving/" +
  std::to_string(x_coordinates[i]) + "," + std::to_string(y_coordinates[i]) +
  ";" + std::to_string(x_coordinates[j]) + "," +
  std::to_string(y_coordinates[j]) + "?annotations=distance";
curl_easy_setopt(curl, CURLOPT_URL, url);

What you want to do:

const std::string url = "http://localhost:5000/route/v1/driving/" +
  std::to_string(x_coordinates[i]) + "," + std::to_string(y_coordinates[i]) +
  ";" + std::to_string(x_coordinates[j]) + "," +
  std::to_string(y_coordinates[j]) + "?annotations=distance";
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
//                                      ^^^^^^^

Upvotes: 2

Related Questions