4

NI-VISA 5.1.1 を使用して、USB 経由でオシロスコープと通信しようとしています。私の 32 ビット アプリケーションは、C++ と MinGW コンパイラ (標準の Qt 4.7 SDK) を使用して Qt フレームワークで作成されています。

Visa32.lib に静的にリンクすると、アプリケーションはデバイスとの通信に問題はありません。私の動的にリンクされたコードは、Windows 7 64 ビット プラットフォームでも正常に動作しますが、Windows XP SP3 (32 ビット) で動作する 2 台の異なるコンピューターではクラッシュします。クラッシュの原因となったコード行を追跡しました (これは viWrite への最初の呼び出しです)。

この問題は、DLL 自体のグローバル変数の設定に関連しているようです。Windows 7 で 32 ビットの DLL ファイルが 64 ビットの VISA DLL ファイルを呼び出すスタブにすぎないため、Windows 7 で動作する理由がこれで説明できるかもしれません。

これは、エクスポートされた関数に動的にリンクする方法です。

typedef long (*tviRead)(ViSession, ViPBuf, ViUInt32, ViPUInt32);
typedef long (*tviWrite)(ViSession, ViBuf, ViUInt32, ViPUInt32);

QLibrary visa32("visa32");   // Qt wrapper for LoadLibrary
if (!visa32.load()) throw "Unable to load visa32.dll";
pviWrite = (tviWrite) visa32.resolve("viWrite");
pviRead = (tviRead) visa32.resolve("viRead");

以下を呼び出すと (vi接頭辞付きの関数は静的にリンクされ、pvi の関数はランタイムにリンクされます)、

status = viOpenDefaultRM(&rm);
status = viFindRsrc(rm, query, &list, &itemCnt, desc);
status = viOpen(rm, desc, VI_NULL, VI_NULL, &vi);
status = pviWrite(vi, (ViByte*) idn, 5, &retCnt);       // Crash right here
status = pviRead(vi, (ViByte*) id, sizeof(id), &retCnt);

すべてが完璧に機能します。ただし、3 つのセットアップ関数のいずれかをランタイム リンクに変更すると、pviWrite を呼び出すときにセグメンテーション エラーが発生します。「グローバル変数を設定する」ためにDLLによってエクスポートされた他の関数はありません。実際、依存関係ウォーカーツールを使用してエクスポートされたDllMainは表示されません。Visa32.dll に正常にリンクされたランタイムはありますか? インターネット上で例を見つけることができません。

4

1 に答える 1

1

次の問題があると思われます。

http://msdn.microsoft.com/en-us/library/ms684179(v=vs.85).aspx

注釈セクションまで下にスクロールし、「Visual C++」を探します。DLL に _declspec スタイルのスレッド ローカル ストレージが含まれている場合は、Vista 以降でのみ動的にロードできます。

私は同じことを達成しようとしていますが、どうやら、XPの場合、単に運が悪い...

于 2013-07-24T09:53:15.297 に答える