1
  1. MyDll.dll を呼び出し、curl を使用してコールバック関数でデータを受信する MainProgram.exe があります。
  2. curl インスタンスを作成して curl_easy_perform を実行する CurlGetData という関数で curl をラップしました。

これが私のコードです:

//Interface class to derive from
class  ICurlCallbackHandler
{
public:
    virtual size_t CurlDataCallback( void* pData, size_t tSize ) = 0;
};

//Class that implements interface
class CurlCallbackHandler : public ICurlCallbackHandler
{
public:
    bool m_exit = false;

    virtual size_t CurlDataCallback( void* pData, size_t tSize ) override
    {
        if(m_exit)
            return CURL_READFUNC_ABORT;

       // do stuff with the curl data

        return tSize;
    }
}


CurlCallbackHandler *m_curlHandler;

//Create an instance of above class in my dll constructor
MyDll:MyDll()
{
    m_curlHandler = new CurlCallbackHandler();
}

//Cleanup above class in my dll destructor
MyDll:~MyDll()
{
    delete m_curlHandler;
    m_curlHandler = nullptr;
}

//Function to start receiving data asynchronously  
void MyDll::GetDataAsync()
{
    std::async([=]
    {
        //This will receive data in a new thread and call CurlDataCallback above
        //This basically calls easy_perform
        CurlGetData(m_curlHandler);
    }
}

//Will cause the curl callback to return CURL_READFUNC_ABORT
void MyDll::StopDataAsync()
{
    m_curlHandler->m_exit = true;
}

GetDataAsync 関数は私のメイン プログラムから呼び出され、基本的に curl_easy_perform を呼び出し、m_curlHandler をそのコールバック関数として使用して、CurlDataCallback を呼び出します。

これはすべて正常に動作しますが、メイン プログラムが終了するたびに MyDll::StopDataAsync が呼び出され、curl データ コールバックが停止され、MyDll のデストラクタが呼び出されて m_curlHandler がクリーンアップされます。

しかし、その時点でcurlはこのコールバックをまだ終了しておらず、 m_curlHandler が削除されているためプログラムがクラッシュしますが、新しい非同期スレッドのcurlコールバックはまだそれを使用しています。

正常に終了することもありますが、curlcallback がデストラクタによって削除されたポインタにアクセスしようとするためにクラッシュすることもあります。

m_curlHandler をクリーンアップするにはどうすればよいですか? これはメイン プログラムのパフォーマンスに影響するため、待機タイムアウトを入れないようにしたいと考えています。

4

1 に答える 1