Pass data as void * in C ++
I am using curl in my C ++ program. Curl can store the "user data" that is passed to it so that when I receive the swirling HTTP callback, I can get that user data again.
Curl will store this data as void *. I want to be able to pass data to a function like this:
void SomeFunction( const std::string& url, const std::string& username, const std::string& password, void* userData)
{
//Pass userData to curl..blah blah
}
My question is what is the correct and correct C ++ way to pass data as void * ?? Should I have an interface like this:
class ICurlUserData
{
public:
virtual void SetCurlData( void* pUserData ) = 0;
virtual void* GetCurlData( void ) = 0;
};
And then the class implements this interface as follows:
class CurlUserData
{
public:
CurlUserData() : m_userData(nullptr){};
virtual ~CurlUserData(){};
virtual void SetCurlData( void* pUserData ){ m_userData = pUserData;}
virtual void* GetCurlData( void ){ return m_userData; }
private:
void* m_userData;
};
And pass it like this:
void SomeFunction( const std::string& url, const std::string& username, const std::string& password, ICurlUserData* userData)
{
CurlUserData data = static_cast<CurlUserData*>(userData);
void* myData = data->GetCurlData();
int myNumber = static_cast<int>(myData);
//blah blah
}
Thanks for any help
source to share
The correct way to pass data void*
to curl
C functions (or any other) calling you is like this:
StronglyTyped myobj;
extern "C" void myfunc (void* arg)
{
StronglyTyped* p_myobj = static_cast<StronglyTyped*>(arg);
// do something
}
//.. somewhere in your code ...
curl_something(curlarg1, curlarg2, myfunc, static_cast<void*>(&myobj));
These three entries void*
should be the only ones you are using.
Update after discussing comments .
There is no way to get rid of these void*
occurrences. A C function cannot use templates, derived classes, or all sorts of other advanced methods. If he wants to call a custom function and pass some custom data back, it must work with void * pointers. Thus, a C function that requires a callback usually takes two parameters that look like this:
void c_function_with_a_callback ( ..., ...,
void (*user_function)(void*),
void* user_data);
Two valid parameters passed to a function must have exactly the types specified in the signature, so one must write a function that has this signature:
void somefunction (void*);
and must have a pointer void*
to pass it on. The latter is usually obtained from a regular object pointer by casting. somefunction
usually restores the strongly typed object pointer in the first line.
It is not necessary to have any other pointer void*
— not any given by the "curl" function.
Indeed, if the offending function is to be written in C ++, it could easily be a function template:
template <typename T>
void void cxx_function_with_a_callback (..., ...,
void (*user_function)(T*),
T* user_data);
Not found void*
anywhere in this version, but it is fundamentally identical to version C. The only differences between system with c_function_with_a_callback
and system with a cxx_function_with_a_callback
are:
- A type
user_function
- A type
user_data
- The presence or absence of two castings from and to
void*
If system c cxx_function_with_a_callback
does not have void*
anywhere, a similar system c c_function_with_a_callback
should have pointers void*
exactly at the locations listed above and nowhere else. If system c cxx_function_with_a_callback
requires for some reason void*
, then system c c_function_with_a_callback
will also require void*
similar places, but these things void*
have nothing to do with how c_function_with_a_callback
user data is stored .
source to share