この質問の背景には、以前の質問があります。 非メンバー関数ポインターが API 内のメンバー関数へのコールバックとして使用されています(無関係かもしれません)。
コールバックは、データを書き込むスレッドを起動します。同じデータを読み取る別のスレッドがあり、その結果、いくつかのクラッシュが発生します。マルチスレッドの集中講座を受講したところです (SO に感謝します)。データがライターとリーダーによって同時にアクセスされないことを保証する試みを次に示します。Qt (QReadWriteLock) のミューテックス メカニズムを使用しています。
#include <QSharedPointer>
#include <QReadWriteLock>
Class MyClass
{
public:
MyClass();
bool open();
float getData();
void streamCB(void* userdata);
protected:
float private_data_;
QSharedPointer<QReadWriteLock> lock_;
};
// callback wrapper from non-member C API to member function void
__stdcall streamCBWrapper(void* userdata)
{
static_cast<MyClass*>(userdata)->streamCB(userdata);
}
// constructor
MyClass::MyClass()
{
lock_ = QSharedPointer<QReadWriteLock>(new QReadWriteLock());
lock_->lockForWrite();
private_data_ = getData();
lock_->unlock();
}
// member callback
void MyClass:streamCB(void* userdata)
{
float a = getData();
lock_->lockForWrite(); //*** fails here
private_data_ = a;
lock_->unlock();
}
プログラムの実行中にセグメンテーション違反が発生しました。VSデバッガーはAccess violation writing location 0x00fedbed.
、私がマークした行に、//*** fails here.
ロックはコンストラクターで機能しましたが、コールバックでは機能しませんでした。
何がうまくいかないのですか?何を見ればいいですか?(そしてどうすれば私の質問を絞り込むことができますか)ありがとう!
その他の関連スレッド クラス 'QReadWriteLock'Error 1 エラー C2248: 'QReadWriteLock::QReadWriteLock' で宣言されたプライベート メンバーにアクセスできません(私は QSharedPointer の提案を使用しました)
編集1: コールバックが設定されています
bool MyClass::open()
{
// stuffs
int mid = 0;
set_stream_callback(&streamCBWrapper, &mid);
// more stuffs
return true;
}
編集 2: すべての提案に感謝します。私の間違いは、ミューテックスが原因ではなく、API を理解していないことが原因でしょうか? 私はかなり混乱しています..これはset_stream_callbackのAPIドキュメントです。
typedef void (__stdcall *STREAM_CALLBACK)(void *userdata);
/*! @brief Register a callback to be invoked when all subscribed fields have been updated
*
* @param streamCB pointer to callback function
* @param userdata pointer to private data to be passed back as argument to callback
* @return 0 if successful, error code otherwise
*/
__declspec(dllimport) int __stdcall set_stream_callback(
STREAM_CALLBACK streamCB, void *userdata);