cURL / Mailing Lists / curl-users / Single Mail

curl-users

Mistake in user guide documentation regarding C++ (lib-curl-the-guide)

From: Nye, Jason <jnye_at_osii.com>
Date: Sun, 11 Jul 2004 20:37:36 -0500

Hello all,
 
I was just reading the documentation for curl for the first time when I
saw the section on C++ which is wrong. The section says:
 
libcurl with C++
 
 There's basicly only one thing to keep in mind when using C++ instead
of C
 when interfacing libcurl:
 
    "The Callbacks Must Be Plain C"
 
 So if you want a write callback set in libcurl, you should put it
within
 'extern'. Similar to this:
 
     extern "C" {
       size_t write_data(void *ptr, size_t size, size_t nmemb,
                         void *ourpointer)
       {
         /* do what you want with the data */
       }
    }
 
 This will of course effectively turn the callback code into C. There
won't be
 any "this" pointer available etc.

 
The statement saying "The callbacks must be Plain C" should be replaced
with "The callbacks CANNOT be non-static class member functions". The
discussion about extern "C" is all wrong. All extern "C" does is prevent
name mangling and has nothing to do with the this pointer or how
function pointers at runtime are interpreted.
 
For example, the following function (note that it is even part of a
class) is a perfectly valid callback:
 
class AClass {
....
    static size_t MyCURLCallback(void *ptr, size_t size, size_t nmemb,
void *ourpointer)
    {
        ...
    }
};
 
Try it -- you'll see that it works just fine. You just need to pass it
to the library as AClass::MyCURLCallback and it will work fine. If a
method of AClass is passing the pointer to the curl library, then it can
simply specify MyCURLCallback.
 
Note the lack of extern "C". All that a callback requires is that there
is no 'this' pointer. This is achieved by using a static member
function. Global functions in C++ also do not have 'this' pointers and
are also perfectly valid (again, with no extern "C").
 
The only time extern "C" ever comes into play is at the link stage -- if
a function, void f(int i) is compiled by C++, it will end up looking
something like Vfunc1I in the object file (function that returns void,
called f that takes 1 integer parameter). This only affects clients that
EXPLICITLY link to void f(int i). This is why you see extern "C" in all
C headers -- if it wasn't there, your C++ compiler would generate
function symbols like Istrcmp2CCP which would not link to the standard
library because its symbol is "strcmp". Extern "C" simply ensures that
C++ will leave int strcmp(const char *, const char *) as "strcmp" --
that's it.
 
I've seen endless discussions of this type in the pthreads_ newsgroups
about the thread start routine and it is all wrong. Extern "C" does
_nothing_ to function pointers as there is no name in running code, just
an address.
 
Cheers to all. Sorry if this sounds like a rant -- it isn't.
 
 
 
Jason Nye
Software Engineer
Open Systems International, Inc.
3600 Holly Lane North, Suite 40
Minneapolis, MN 55447-1286
Phone: (763) 551-0559
Fax: (763) 551-0750
E-mail: jnye_at_osii.com
www.osii.com <http://www.osii.com/> , www.e-scada.com
<http://www.e-scada.com/>
 
Received on 2004-07-12