0

これを試みる人々は通常、オラクルまたはC ++のいずれかで無能であるため、主題に関する情報はあまりなく、そこを掘り下げようとする人には多くの問題があります(たとえば、私は完全なオラクル初心者です)。

両者の境界線は、まさに暗くもどかしい領域です。この投稿は、イライラを軽減すること、または少なくとも暗くすることを目的としています.

C++ コードへの実際のリンクについては、ほとんどのマニュアルで説明されているので、ここでは説明しません。代わりに、問題を引き起こす可能性が最も高いいくつかのことについて話したいと思います。

下記参照:

dllキャッシング

静的変数

デフォルト パス

イベントループ

私が行っていることは好ましくない可能性が高いため、解決策を提案するのではなく、私の経験を共有しているだけであることに注意してください. だから、私は議論を歓迎します。

4

1 に答える 1

0

私の作業構成はCentos 5.5 + Oracle XE + Qt4.7であることに注意してください

重要

QxtLogger (またはそれに類するもの) はあなたの親友です。extproc を介して呼び出しをデバッグすることはできないため、たくさんログに記録します。あるいは地獄になる。(とにかく地獄になるでしょうが、少なくともあなたは揚げられ、同時に盲目になることはありません). Q xtに注意してください。これは、いくつかの本当に便利なもので Qt を拡張する、気の利いた小さなライブラリではありません。

DLL キャッシング

extproc が呼び出されると、キャッシュされたバージョンの DLL がハード ドライブ上のバージョンと比較され、新しいバージョンがロードされると言われています。これが常に当てはまるとは限らないことがわかりました。HDD に存在するライブラリよりも古いバージョンのライブラリに対してパーサー呼び出しが行われるのを何度も見てきました。すぐにではなく、自動的に修正されます。覚えておいてください。

提案:ライブラリのバージョンを常にファイルに記録して、実際に何が起こっているかを確認してください。

静的変数

オラクルがその点について何を言わなければならないかを見落とすのは非常に簡単です(特に、あなたが私のようにオラクルに慣れていない場合、ほとんどすべてのドキュメントはほとんどまたはまったく意味がありません). これは重要ですが。静的関数変数、前述の dll キャッシュにより機能する場合がありますが、機能することは保証されていません

たとえば、これは私たちが職場で最初にテストしたものです。

「ライブラリを作成し、静的変数で func を作成し、結果として 2 つの呼び出しを作成し、保持されていることを確認し、喜んで DLL アプローチを使用します」

これは間違っていました:(

つい最近、これらの「保持された変数」が保持されなくなったことに気付きました...そして、各呼び出しはDBから辞書を「プリロード」するのに約1秒かかります...笑。

提案: extproc 呼び出しは、サーバー上に既に存在するプロセスを何らかの方法で呼び出す必要があります。たとえば、私の場合、パーサー ライブラリを、サーバー上で常に実行される実行可能ファイルと、QxtRPCPeer (Qt アプリケーション間でシグナル/スロット呼び出しを転送するツール) を介してこのプロセスとデータを交換するライブラリに分離しました。

デフォルトのパス:

うん。qxtLog->debug(QDir::currentPath()); を呼び出してみてください。extproc から呼び出された Dll。これはまったくおかしなことではなく、フラストレーションがたまる可能性があります。extproc で呼び出されたライブラリでパスに依存するものを使用する場合は 、パスを自分で設定してください

可能性があります: この問題により、QOCI ドライバーが sqldrivers フォルダーから自動的に読み込まれなくなります。代わりに次のコードを使用してください。

QPluginLoader loader("sqldrivers\\qsqlocid4.dll");
qxtLog->trace(loader.fileName());
QObject *plugin = loader.instance();
qxtLog->trace(loader.errorString());
if (!plugin)
    return;

QSqlDriverPlugin *sqlPlugin  = qobject_cast<QSqlDriverPlugin *>(plugin);

if (!sqlPlugin )
    qxtLog->critical("Failed to load plugin");
else
    qxtLog->trace("Successfull plugin load");

QSqlDriver * driver = sqlPlugin->create("QOCI");
db = QSqlDatabase::addDatabase(driver, "Connection name");

アプリケーションが失敗する理由をいつでも確認できるように、ログが記録されます。

QDir::currentPath がどこかを指すように設定された後は、"sqldrivers\qsqlocid4.dll" のようなものしか使用できないことに注意してください。

イベントループ:

明らかに-そのようなライブラリのイベントループはありません。QCoreApplication::instance() も NULL を返します。意味 - シグナル/スロット呼び出しはありません。試してはいけません。そのようなシナリオでシグナルを適切に使用する方法を誰かに教えてもらいたいです。私の仕事では、 QProcess を呼び出して(実際にすべての作業を行います)、イベントループなしで動作する神々の関数 QProcess::waitForFinished() を使用して解決しました

だから、これらは私の観察です。お気軽に訂正してください。適切な方法を教えていただけると幸いです。

于 2012-08-02T21:07:01.533 に答える