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 に正常にリンクされたランタイムはありますか? インターネット上で例を見つけることができません。