2

ネットワークを実行したい dll があります。この dll は、C# アプリケーションからアンマネージ DLL として呼び出されます。すべての初期化は正常に機能しますが、->get() が実行されるたびにフリーズします。私はこのコードを持っています:

.........
QUrl path(remotePath);
QNetworkRequest request(path);

currentFile.setFileName(localPath);
if(!currentFile.open(QIODevice::WriteOnly)){
doCallback("failed to open: " + localPath);
}
doCallback("before get: " + remotePath);
QNetworkReply* reply = this->manager->get(request);
doCallback("after get: " + localPath);
...........

「取得前」のコールバックは正常に実行されますが、「取得後」のコールバックは実行されないため、マネージャーが Get() メソッドを試行すると完全にフリーズすると思います。私は何かを見逃したことがありますか、それとも DLL では不可能ですか?

4

2 に答える 2

1

私の推測では、あなたの QT ライブラリは opensll に対して構築されたものです。QNetworkAccessManager は、ssl dll、libeay32.dll および ssleay32.dll を探します。Win32 LoadLibrary は、これらの dll をロードしようとしている間、プロセス全体、UI、シグナル スロットなどすべてをハングさせます。これらの dll を実行可能ファイルのディレクトリにコピーすると、読み込みがすぐに成功します。

于 2013-02-20T00:37:57.813 に答える
0

わかりましたので、これが機能するようになったので、知識を共有したいと思いました。アンマネージ dll を使用して、新しい QCoreApplication を作成する init 関数をエクスポートしました。これにより、後ですべてのネットワークを実行するクラスの親として QCoreApplication オブジェクトを使用してイベント ループを使用できます。

QCoreApplication* coreApp = 0;
extern "C" __declspec(dllexport) void initdll()
{
    if (!coreApp) {
        int argc    = 0;
        coreApp = new QCoreApplication(argc, 0);
    }
    if(!MyFunc){
        MyFunc = new QtDll(coreApp);
    }
}

ネットワーキングを試す前に C# (または何でも) アプリケーションでこの init 関数を呼び出すことで、イベント ループの exec を追加することで、最初の投稿のコードで動作するようになりました。

QNetworkReply* reply = this->manager->get(request);
currentReply = reply;
QEventLoop eLoop;
connect(reply, SIGNAL(readyRead()), this, SLOT(slotReadyRead()));
eLoop.exec( QEventLoop::ExcludeUserInputEvents );

フィードバックをお寄せいただきありがとうございます。

于 2012-08-09T09:05:47.530 に答える