- У меня есть файл MainProgram.exe, который вызывает MyDll.dll и использует curl для получения данных о функции обратного вызова.
- Я завернул curl в функцию CurlGetData, которая создает экземпляр curl и выполняет curl_easy_perform.
Вот мой код:Как правильно удалить указатель на функцию обратного вызова.
//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 в новом потоке async все еще использует его.
Иногда он закрывается нормально, но в других случаях он падает из-за зависания, пытающегося получить доступ к указателю, который был удален деструктором.
Как лучше всего очистить m_curlHandler? Я хочу избежать задержки ожидания, так как это повлияет на производительность моей основной программы.