1

現在、Qt で奇妙な問題に直面しています。QTcpSocket を使用して複数のクライアントを処理するアプリケーションがあります。クライアントはサーバーにログインの詳細を提供し、サーバーは別のスレッドで資格情報を確認するために MySQL データベースをチェックします。

このサーバーにログインする 2 つの異なるクライアント プログラムがあります。 1. Qt を使用してそこに接続する単純なクライアント 2. C-Sharp (.net) でコーディングされたクライアント

でも

2 番目のクライアントがサーバーにログインしようとすると、サーバーで次のようなエラーが表示されます。

QObject: 別のスレッドにある親の子を作成できません。親は QNativeSocketEngine(0x1231e00)、親のスレッドは QThread(0xc625f0)、現在のスレッドは CMySQLHandler(0xc67188) です。

これは MySQL ハンドラー スレッドで発生していると推測していますが、奇妙なことに、Qt でコーディングされたクライアントではまったく発生していません。

コードは次のとおりです。

void CMySQLHandler::onAuthRequest(ulong clientID, QString email, QString psw, QString HWID, QString ip)
{

    string pass = "", salt = "", name = "", avatar = "";
    uint UserID = 0;
    CUserData *extra = new CUserData();
    bool success = false;
    QString failReason = "Success";

    string Query = "SELECT password, username, avatar, userid FROM jos_users LEFT JOIN jos_community_users ON jos_users.id = jos_community_users.userid WHERE email = '"+email.toStdString()+"'";
    SQLRow Row = GetRow(Query);

    if(!Row.empty())
    {
        QString hashedPass = QString(Row[0].c_str());
        pass = hashedPass.split(':').at(0).toStdString();
        salt = hashedPass.split(':').at(1).toStdString();


        name = Row[1];
        avatar = Row[2];
        UserID = QString(Row[3].c_str()).toUInt();
        QByteArray data;
        data.append((psw + QString(salt.c_str())));
        QString blah = QString(QCryptographicHash::hash(data,QCryptographicHash::Md5).toHex());
        if(QString(pass.c_str()) == blah )
            success = true;
        else
            failReason = "Invalid password";

    }
    else
    {
        failReason = "E-Mail not found";
        emit Handle->onAuthCompleted(clientID, false, failReason, extra);
        return;
    }

    extra->Avatar += avatar.c_str();
    extra->UserID = UserID;

    extra->Username = QString(name.c_str());

    emit Handle->onAuthCompleted(clientID, true, QString(), extra);
}

ここに信号の定義があります

void CMySQLHandler :: onTimerInit()
{

    //Authentication
    connect(this, SIGNAL(doAuthCompleted(ulong,bool,QString,CUserData*)), Handle, SLOT(onAuthCompleted(ulong,bool,QString,CUserData*)));
    connect(Handle, SIGNAL(doRequestAuth(ulong,QString,QString,QString,QString)), this, SLOT(onAuthRequest(ulong,QString,QString,QString,QString)));
    //end


    CMySQL::Init(Handle);
}

私は Qt フレームワークが初めてです。知識不足をお許しください。

これを読んでいただきありがとうございます。

4

2 に答える 2

0

Qtは、スレッドによるオブジェクトの所有権の概念を使用します。シグナル/スロットメカニズムを実行するために、独自のオブジェクトをスレッド化します。問題は、スレッドCMySQLHandler(0xc67188)で新しいオブジェクトを作成し、それに親QNativeSocketEngine(0x1231e00)を割り当てようとしていることです。ただし、QNativeSocketEngineはQThread(0xc625f0)によって所有されており、許可されていません。コードにエラーが表示されないため、エラーの原因となっている行を見つけて質問を編集するために、さらにデバッグを行う必要がある場合があります。

于 2012-11-13T13:43:20.480 に答える
0

この種の異なるスレッドの問題は、複数のスレッドを使用する Qt で常に発生します。この問題を解決する標準的な方法は、シグナルとスロットを使用することです。

エラーは では発生しません。onAuthRequestおそらく、この関数を呼び出そうとした時点で発生します。CMySQLHandlerあるスレッドでオブジェクトを作成し、別のスレッドでそのメンバー関数を実行しようとしている可能性があります。

何らかの理由で別の脅威に属するオブジェクトの関数を呼び出す必要がある場合は、slot関数をラップするオブジェクトに を作成し、emit.

同様の質問QObject: Cannot create children for a parent that is in different thread を参照してください

于 2012-11-13T14:05:10.183 に答える