LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Newbie to libcurl API in C++ - Basic example (https://www.linuxquestions.org/questions/programming-9/newbie-to-libcurl-api-in-c-basic-example-708034/)

matiasar 02-27-2009 12:20 PM

Newbie to libcurl API in C++ - Basic example
 
Hello!
I'm new to libcurl and quite newbie to C++. I'm trying to undestand how to send files to a FTP remote host.
I basically understood the example provided with libcurl-dev package (/usr/share/doc/libcurl-devel-7.18.2/ftpupload.c).
Trying to implement libcurl with my C++ program I found difficults.
As it is said in the libcurl doc, to implement Easy API with C++ requires some modifications:


libcurl with C++

There's basically only one thing to keep in mind when using C++ instead of C when interfacing libcurl:

The callbacks CANNOT be non-static class member functions

Example C++ code:

class AClass {
static size_t write_data(void *ptr, size_t size, size_t nmemb,
void *ourpointer)
{
/* do what you want with the data */
}
}



Does anybody knows where I can get a C++ basic example on how to use libcurl's easy API to upload files?

Thanks in advance,
Matías

raconteur 02-27-2009 05:31 PM

Your libcurl package should have come with an examples directory, have you looked there?
ftpupload.c is a good place to start.
As for the static callback, it just means that any callback function that you pass to curl must be declared as a static member function if it is encapsulated in a class.
That prevents moveable classes from being yanked out from under the write process.
Global functions would work just as well, if you didn't want to make the callback a member function.
Other than that, I think all of the curl_easy* functions are the same in C as C++.
If there's something there that isn't clear to you, please ask...

matiasar 02-28-2009 09:31 AM

Thanks for your answer Raconteur.
I left my example code at job. But I'll see if I can try to write uploadftp program in C++ this weekend at home. I'll let you know my results or doubts...

Thank you very much,
Matías

matiasar 03-02-2009 07:00 PM

Well, I finally was able to do it work, with C++.

My guide was g++ warnings / errors. I found that I had to do some little change in the callback function. This way:


Code:

class UploadFtp
{

        static size_t read_callback(void *ptr, size_t size, size_t nmemb, FILE* stream)
        {
          /* in real-world cases, this would probably get this data differently
            as this fread() stuff is exactly what the library already would do
            by default internally */
          size_t retcode = fread(ptr, size, nmemb, stream);

          fprintf(stderr, "*** We read %d bytes from file\n", retcode);
          return retcode;
        }


        private:

            char user [20];
            char pwd [20];
            char remote_url [128];
            char local_file [128];
            char remote_filename [128];


        public:
        (...)

Based on g++ I changed the void pointer "void * stream" to "FILE * stream". Code is working. But I'd like to know more details on how the callback function works and why is needed? Do you have some clue where I can find more info about it?

Regards,
Matías

raconteur 03-03-2009 11:30 AM

The stream pointer in the default implementation is declared as a void pointer to allow it to be cast as necessary. It could be an ostream class or file descriptor, etc. Your implementation is good, there are many different ways to do it.

When you make a call to a function in a dynamically linked library, it is sometimes necessary for that library to "call back" into the calling application.
In this case, libcurl needs to know what to do with the data it is recieving or transmitting (where and how to store it or where and how to get it).
The library needs that to be a rather open interface to be flexible, so it provides a framework for the library to call back to user-defined functions.

matiasar 03-03-2009 07:30 PM

Thank you very much for your explanation. It's much clearer for me now.


All times are GMT -5. The time now is 06:44 PM.