在C ++中将数据作为void *传递

时间:2014-11-09 17:56:54

标签: c++ curl interface

我在我的c ++程序中使用curl。 Curl可以存储传递给它的“用户数据”,这样当我收到curl HTTP回调时,我就可以再次检索这个用户数据。

Curl将此数据存储为void *。我希望能够将数据传递给像这样的函数:

void SomeFunction( const std::string& url, const std::string& username, const std::string& password, void* userData)
{
    //Pass userData to curl..blah blah
}

我的问题是将数据作为void *传递的正确和正确的C ++方法是什么? 我应该有这样的界面:

    class ICurlUserData
    {
    public:
        virtual void SetCurlData( void* pUserData ) = 0;
        virtual void* GetCurlData( void ) = 0;
    };

然后让类实现这样的接口:

    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;
    };

然后通过它:

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
}

感谢您的帮助

1 个答案:

答案 0 :(得分:2)

void*数据传递给调用您的curl(或任何其他)C函数的正确方法如下:

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));

void*的这三次出现应该是您使用的唯一。

更新,继续进行评论讨论

无法摆脱这些void*次出现。 C函数不能使用模板,派生类或各种其他高级技术。如果它想要回调用户函数并将一些用户数据传回给它,它必须使用`void *指针。因此,需要回调的C函数通常接受两个看起来像这样的参数:

void c_function_with_a_callback ( ..., ..., 
                                void (*user_function)(void*), 
                                void* user_data);

传递给函数的两个实际参数必须完全签名中指定的类型,因此一个必须编写具有此签名的函数:

 void somefunction (void*);

并且必须有一个void*指针传递给它。后者通常通过强制转换从常规对象指针获得。 somefunction通常会在第一行中恢复强类型对象指针。

不需要任何其他void*指针 - 不受任何有问题的“卷曲”功能的指示。

的确,如果违规函数是用C ++编写的,它很容易成为函数模板:

template <typename T>
void void cxx_function_with_a_callback (..., ...,
                                       void (*user_function)(T*),
                                       T* user_data);

此版本中的任何位置都没有void*,但它与C版本基本相同。具有c_function_with_a_callback的系统和具有cxx_function_with_a_callback的系统之间的唯一区别是:

  1. user_function
  2. 的类型
  3. user_data
  4. 的类型
  5. 来自void*
  6. 的两个演员阵营的存在与否

    如果cxx_function_with_a_callback的系统在任何地方都没有void*,那么c_function_with_a_callback的类似系统应该在上面列举的地方和其他地方都有void*个指针。如果cxx_function_with_a_callback的系统由于某种原因需要void*,那么c_function_with_a_callback的系统在类似的地方也需要void*,但这些void*的东西与c_function_with_a_callback存储用户数据的方式无关。