DLLを呼び出すとLabVIEWがクラッシュするのはなぜですか?
使用ソフトウェア:
使用ソフトウェア・バージョン: N/A
使用ソフトウェア・バージョンに特化: N/A
二次のソフトウェア: LabVIEW Development Systems>>LabVIEW Professional Development System, LabVIEW Development Systems>>LabVIEW Base Package
問題: LabVIEWでライブラリ関数呼び出しノードを使用してDLLを呼び出すと、LabVIEWがクラッシュします。これはなぜでしょうか?
解決策: DLL呼び出しにおいて、LabVIEWがクラッシュする場合、以下のよう原因/解決策が考えられます。
- DLLに適した呼び出し規約を指定していることを確認してください。
呼び出し規約に Cを指定した場合、呼び出し側でスタックを開放しなければいけません。Stdcallを指定した場合、呼び出された関数がスタックを開放をしなければいけません。呼び出し側(この場合はLabVIEW)と呼び出される側(DLL)の呼び出し規約が一致してい場合、両方がスタックを開放してしまうか、いずれもが開放しないという状態になります。いずれの場合も、DLLの関数呼び出しが終了した時点で LabVIEWがクラッシュします。
- DLLがLabVIEWのメモリを上書きしないように注意してください。
LabVIEWがDLLにポインタを渡すとき、配列、文字列、クラスタなどのポインタ格納用にメモリを確保する必要があります。DLLがメモリ領域に情報を書き込む場合、通常、引数で渡したポインタを、呼び出し後に再度読み込みます。
これは、LabVIEW ではライブラリ関数呼び出しノードの右側の端子を読み出すことと同義です。一般に、DLL に渡す引数は配列のサイズやデータ構造のサイズを表す数値で、関数側がどれだけのメモリが割り当てられているのか分かるようになっています。十分なメモリが確保されていなかったり、DLLが確保されていないメモリ領域に書き込んだ場合、LabVIEW用のメモリ領域に上書きされるためクラッシュします。
- LabVIEWからDLLにデータを渡す場合、引数がDLLが受け取る型で、渡すようにしてください。
LabVIEWとDLLが異なった引数の型(値、ポインタ、ハンドルなど)でやりとりする場合、期待に反してDLLが不適切なメモリにアクセスします。結果として、誤ったデータを受け取ったり、最悪の場合にはLabVIEWやWindowsがクラッシュする場合があります。
- DLLが、ライブラリ関数呼び出しノードの左側の端子から入力されたメモリ領域に書き込む場合、対応する右側の端子から配線を引き出してください。
右側の端子を配線しない場合、LabVIEWはDLLがそのメモリを使用しないと想定し、別の作業用にメモリを割り当てます。結果として、DLLがLabVIEWのメモリ領域を上書きし、LabVIEWがクラッシュする原因になります。
- LabVIEWで作成したDLLのフロントパネルを表示している場合、2つの厳密な制約があります。
- ライブラリ関数呼び出しノードでは、DLLの呼び出しは再入可能に設定する必要があります。これは、ライブラリ関数呼び出しノードをダブルクリックし、実行をUIスレッドの実行 から再入可能に変更することで実現できます。
- DLLを呼び出すVIはユーザインタフェース実行システムで実行されてはなりません。これをチェックするには、DLLの呼び出しを行うVIのファイル » VI プロパティ » 実行 の中から、実行システムの設定は 標準、計測器I/O、データ集録、その他1、あるいはその他2 になっていることを確認してください。
関連リンク: 技術サポートデータベース 3OUJ9U4B: When Does The DLL Specified By A Call Library Function Node Get Loaded Into Memory?
製品マニュアル: Using External Code in LabVIEW
添付:
報告日時: 04/08/2005
最終更新日: 10/04/2009
ドキュメントID: 3K7FBKDW
Other Support Options
Ask the NI Community
Collaborate with other users in our discussion forums
Request Support from an Engineer
A valid service agreement may be required, and support options vary by country.