Как я могу передать boost :: shared_ptr как указатель на функцию Windows Thread? - PullRequest
5 голосов
/ 24 февраля 2011

Как я могу передать boost :: shared_ptr как указатель на функцию Windows Thread? предположим следующий код:

test::start()
{
    ....
    _beginthreadex( NULL, 0, &test::threadRun, &shared_from_this(), 0, &threadID );

    ...
    ...
}

/*this is a static function*/
UINT __stdcall test::threadRun( LPVOID lpParam )
{ 
     shared_ptr<test> k = *static_cast< shared_ptr<test>* >(lpParam);
     ...
}

Я думаю, что этот код неверен, что вы думаете? как я могу это сделать?

РЕДАКТИРОВАТЬ: я решил мою проблему с помощью boost :: weak_ptr. проверьте мой собственный ответ на этой странице

Ответы [ 4 ]

3 голосов
/ 24 февраля 2011

Когда вам нужно передать параметр из класса в статическую функцию / метод, а у вас есть параметр обратного вызова (обычно в обратном вызове потока), я обычно передаю this обратному вызову. Таким образом, у вас есть одно простое приведение, и у вас есть доступ ко всем членам вашего класса. Практически, обратный вызов как член вашего класса:

test::start()
{
    // [...]
    _beginthreadex(NULL, 0, &test::threadRun, this, 0, &threadID);
    // [...]
}

// this is a static function
UINT __stdcall test::threadRun(LPVOID lpParam)
{ 
     test* self = static_cast<test*>(lpParam);

     // do whatever you want with all the instance members :)

     self->getMyShared();
     self->useMyGreatMemberMethof();

     // ...
}

my2c

1 голос
/ 24 февраля 2011

Я решил свою проблему с помощью Boost :: Strong_ptr:

test::start()
{
    ....
    shared_ptr<test> shPtr = shared_from_this();
    boost::weak_ptr<test> wPtr=shPtr;
    _beginthreadex( NULL, 0, &test::threadRun, &wPtr, 0, &threadID );

    ...
    ...
}

/*this is a static function*/
UINT __stdcall test::threadRun( LPVOID lpParam )
{ 
shared_ptr<test> k      = static_cast< boost::weak_ptr<test>* >(lpParam)->lock();
     ...
}
1 голос
/ 24 февраля 2011

Вы должны использовать reinterpret_cast и позаботиться о том, чтобы у вас был хотя бы один shared_ptr во время нереста. В противном случае ваш объект будет уничтожен. То есть, поскольку вы передаете указатель на shared_ptr, вы не будете пользоваться обычной защитой указателя, и если все ваши существующие shared_ptrs будут уничтожены, то, когда ваш поток порожден, он будет содержать недопустимый указатель.

0 голосов
/ 24 февраля 2011

Это на самом деле одна из ситуаций, когда навязчивый подсчет ссылок работает хорошо.

Если вы хотите передать boost::shared_ptr, вы можете поместить его в структуру с навязчивым подсчетом ссылок и передать ее внутрь.

Предполагается, что вы не просто хотите передать необработанный указатель и заставить получающий поток удалить его, когда закончите.

...