LabVIEWクラスを作成する



LabVIEW 2018ヘルプ


発行年月: 2018年3月
製品番号: 371361R-0112
製品情報を参照

ダウンロード (Windowsのみ)


LabVIEW 2016ヘルプ
LabVIEW 2017ヘルプ
LabVIEW 2018ヘルプ
LabVIEW 2019ヘルプ
LabVIEW 2020ヘルプ

LabVIEWでユーザ定義データタイプを作成するには、LabVIEWクラスを作成します。LabVIEWクラスは、オブジェクトに関連付けるデータ、またデータに対して実行するアクションを定義するメソッドを定義します。カプセル化継承を利用することで、アプリケーション全体に影響することなく変更できるモジュールコードを作成できます。

LabVIEWでは、クラスのデータはプライベートです。つまり、クラスのメンバーであるVIのみがそれらのデータにアクセスできます。クラスのデータは、プライベートデータ制御器で定義します。LabVIEWクラスを作成して保存すると、新しいデータタイプを定義するためのクラスライブラリファイル(.lvclass)がダイナミックに作成されます。クラスライブラリファイルには、プライベートデータ制御器と、作成されたメンバーVIのリストやプロパティなどの情報が記録されます。クラスライブラリは、プロジェクトライブラリ.lvlib)に類似しています。ただし、新しいデータタイプを定義する点で異なります。

プライベートデータ制御器は、新しいデータタイプのデータのクラスタを定義するクラスライブラリファイルで、クラスワイヤ上のデータとなります。プライベートデータ制御器は、ディスク上に保存されず、クラスライブラリファイルに保存されます。プライベートデータ制御器をクラスライブラリファイル内に保存することにより、クラス定義に対して必ず正しいプライベートデータが使用されるようになります。

ヒント  LabVIEWクラスと同じ名前のディレクトリをディスク上に作成して、クラスライブラリファイル、クラスメンバーVIクラスカスタムデフォルトプローブを保存することができます。クラスライブラリがディレクトリで所有するファイルを含めることができます。同じディレクトリに複数のクラスライブラリのファイルを含める場合、異なるクラスライブラリで同じ名前のVIを含めようとすると競合が生じることがあります。ダイナミックメンバーVIを上書きする際、開発プロセスで名前の競合が生じる可能性があります。

カプセル化

各LabVIEWクラスは、データクラスタ、およびクラスタに読み取りおよび書き込みを行うメソッドで構成されています。LabVIEWクラスのデータはすべてプライベートデータか、クラスメンバーであるVIに対して非表示になっています。プライベートデータにアクセスするには、メソッドをクラスのメンバーVIとして作成し、クラスのプライベートデータに対して関数を実行します。カプセル化とは、データとメソッドをクラスに統合することです。これにより、データはクラスのメンバーVIによってのみアクセスされるようになります。カプセル化によって、アプリケーション内の他のコードセクションに影響を与えずに簡単に更新または変更できるコードのモジュールブロックを作成することができます。

クラスのデータは常にプライベートですが、ユーザによるメンバーVIへのアクセスはさまざまなレベルに設定できます。メソッドのアクセススコープは、以下のとおり設定できます。

  • パブリック―VIのどれでもサブVIとしてメンバーVIを呼び出すことができます。
  • コミュニティ―同じクラス、クラスのフレンド、またはクラスのフレンドライブラリ内のVIのみが、メンバーVIを呼び出せます。コミュニティメンバーVIにはプロジェクトエクスプローラウィンドウで濃い青の鍵グリフが表示されます。
  • プロテクト―同じクラスまたは派生クラスのVIのみがメンバーVIを呼び出すことができます。プロジェクトエクスプローラウィンドウでは、プロテクトスコープのメンバーVIには黄色いキーグリフが表示されます。
  • プライベート―同じクラスのVIのみがメンバーVIを呼び出すことができます。プロジェクトエクスプローラウィンドウでは、プライベートメンバーVIに赤い鍵グリフが表示されます。
  • 非指定―このオプションは、フォルダを選択する場合にのみ表示されます。フォルダには指定されたアクセス項目がありません。アクセスはパブリックです。デフォルトでは、クラスのフォルダには指定されたアクセス権がありません。つまり、フォルダはパブリックアクセスが可能であることを意味します。
    メモ  フォルダのアクセスオプションを指定する場合、アクセスの設定はフォルダのすべての項目に適用され、フォルダの個々の項目のアクセスオプションはオーバーライドされます。
メモ  コミュニティスコープに設定すると、ダイナミックディスパッチVIが破損します。プロテクトスコープでダイナミックディスパッチVIにフレンドアクセスを許可するには、フレンドが呼び出すスタティックディスパッチラッパーVIを作成し、そのラッパーVIをコミュニティスコープに設定します。

ライブラリのフレンドを指定する

VIをライブラリのフレンドとして指定し、VIがコミュニテイスコープにあるライブラリの任意のメンバーを呼び出せるようにします。別のライブラリをライブラリのフレンドとして指定することもできます。

フレンド関係は推移的ではありません。たとえば、最初のライブラリが2番目のライブラリをフレンドとして指定し、2番目のライブラリは3番目のライブラリをフレンドに指名した場合、3番目のライブラリは最初のライブラリのフレンドとは見なされません。3番目のライブラリは、最初のライブラリが3番目のライブラリとフレンドとして指定しない限り最初のライブラリのVIにアクセスできません。コミュニティスコープアクセスがあるライブラリがクラスをフレンドとして指定すると、そのクラスのメンバーVIはライブラリのVIにアクセスできますが、このフレンド関係はクラスの派生にはあてはまりません。

LabVIEWクラス外のVIを作成し、パブリックメンバーVIをブロックダイアグラム上でサブVIとして使用できます。パブリックメンバーVIを使用して、クラスのプライベートデータを操作できます。メンバーVIのブロックダイアグラム上でプライベートおよびプロテクトメンバーVIを使用して、LabVIEWクラスユーザに対しては非表示になっているクラスのプライベートデータを操作することができます。クラス外のVIがクラスのフレンドとして指名されている場合、フレンドVIはクラスのコミュニティメンバーを呼び出すことができます。クラスのエントリポイントを制限することでデータ内でのエラーが低減され、コードのデバッグが容易になります。

カプセル化およびLaVIEWクラスのアクセススコープのサンプルについては、以下のプロジェクトを参照してください。

  • labview\examples\Object-Oriented Programming\Data Encapsulation\Data Encapsulation with LabVIEW Classes.lvproj

  • labview\examples\Object-Oriented Programming\Access Scope\Access Scope with LabVIEW Classes.lvproj

プライベートデータ制御器を定義する

LabVIEWクラスを作成すると、クラスのプライベートデータ制御器がダイナミックに作成されます。以下のプロジェクトエクスプローラウィンドウでは、LabVIEWクラスアイコンが色つきのキューブで表示されています。キューブはLabVIEWクラスを表すアイコンです。プライベートデータ制御器は、緑の円柱付きのキューブのアイコンで表されます。円柱は、データストレージを表しています。また、プライベートデータ制御器のアイコンには、この制御器がプライベートであることを示す赤いグリフが表示されます。

クラスのプライベートデータ制御器をカスタマイズするには、制御器エディタウィンドウを使用します。プロジェクトエクスプローラウィンドウでクラスのプライベートデータ制御器をダブルクリックすると、制御器エディタウィンドウが表示されます。クラスプライベートデータのクラスタ内に制御器と表示器を配置して、LabVIEWクラスのプライベートデータタイプを定義することができます。クラスプライベートデータのクラスタの制御器のデフォルト値には、クラスのデフォルト値が使用されます。

メモ  プライベートデータ制御器には、XControlを含めることはできません。

次の例では、Vehicleクラスのデータタイプにはギアの数ドアの数を示す3つの数値と、メーカーモデルという2つの文字列があります。

メモ  クラス内にプライベートデータが必要ない場合は、クラスプライベートデータのクラスタを空白にしておくこともできます。

ブロックダイアグラムまたはフロントパネルのクラスのオブジェクトを視覚的に表すアイコンを作成することができます。クラスプロパティダイアログボックスの一般設定ページで編集ボタンをクリックすると、アイコンエディタダイアログボックスが開きます。まず、クラスのすべてのオブジェクトに適用されるクラスアイコンを作成します。さらに、クラスの各オブジェクトに対してアイコンを修正します。

メンバーVIを作成する

メンバーVIを作成して、クラスのプライベートデータに対する操作を実行できます。メンバーVIは、LabVIEWクラスのメソッドです。メンバーVIは、作成先のLabVIEWクラスのメンバーとして、プロジェクトエクスプローラウィンドウでそのクラスのプライベートデータ制御器の下に表示されます。

クラスのデータはクラスタとして定義されます。任意のメンバーVIは、クラスデータのクラスタに読み取りまたは書き込みを行うことができます。クラスタの個々の要素にアクセスするVIを作成するショートカットが提供されます。これらのアクセサVIは、LabVIEWクラスのメンバーで、クラスタデータに読み取りまたは書き込みを行うことができます。クラスデータを読み取るアクセサVIを作成する場合、以下の画像のようにクラスデータはバンドル解除されます。

クラスデータに書き込むアクセサVIを作成する場合、以下の画像のようにクラスデータに新規の値がバンドルされます。

また、「バンドル解除」関数と「名前でバンドル解除」関数を使用して、メンバーVIのブロックダイアグラムのクラスのプライベートデータをバンドル解除することができます。プライベートデータのクラスタを操作を行った後に再バンドルするには、「バンドル」関数と「名前でバンドル」関数を使用します。クラスのデータはプライベートであるため、メンバー以外のVIのブロックダイアグラムでバンドルノードとバンドル解除ノードでクラスデータを処理しようとするとノードが破損します。

メモ  新規要素をプライベートデータのクラスタに挿入する場合にVIの破損を可能な限り回避するため、「バンドル」または「バンドル解除」の代わりに、「名前でバンドル」および「名前でバンドル解除」関数を使用することを検討してください。

値をバンドル解除して変更し、その値をオブジェクトに戻してバンドルするメンバーVIを書く場合、境界線のバンドル解除ノードとバンドルノードのペアを使用するIn Place要素ストラクチャを使用するとより良いパフォーマンスが得られます。ストラクチャの使用により、特定のメモリ最適化が適用されます。これらの同じメモリ最適化は、通常のバンドル解除ノードとバンドルノードを使用する場合に適用されますが、複雑なVIを使用する特定の環境において、LabVIEWのコンパイラが、この最適化の適用が安全で、適用を回避すると結果的にパフォーマンスが落ちることを認識しないことがあります。ストラクチャノードはこれらの最適化の安全性を保障するので、ご使用のVIの最適化が保証されます。

メンバーVIは、複数の方法で作成することができます。クラスを右クリックしてショートカットメニューから以下のいずれかの項目を選択します。

  • 新規→VI―ブランクメンバーVIを開きます。
  • 新規→プロパティ定義フォルダ―プロパティ定義フォルダを作成します。このフォルダに新しいメンバーVIを作成したり既存のメンバーVIを追加することができます。LabVIEWクラスにプロパティ定義フォルダが含まれる場合は、そのLabVIEWクラスをプロパティノードに配線してプライベートデータにアクセスできます。
  • 新規→ダイナミックディスパッチテンプレートからのVI―新規メンバーVIは、エラー入力クラスタおよびエラー出力クラスタ、エラー処理用のケースストラクチャ、入力LabVIEWクラス、出力LabVIEWクラスで構成されます。入力と出力端子の両方がVIのコネクタペーンでダイナミックとして設定されます。
  • 新規→スタティックディスパッチテンプレートからのVI―新規メンバーVIは、エラー入力クラスタおよびエラー出力クラスタ、エラー処理用のケースストラクチャ、入力LabVIEWクラス、出力LabVIEWクラスで構成されます。スタティックディスパッチVIのコネクタペーンでは、ダイナミックディスパッチVIの場合とは異なり、入出力端子がダイナミックとして設定されません。
  • 新規→データメンバーアクセスのためのVIアクセサを作成ダイアログボックスを開きます。このダイアログボックスで、LabVIEWクラスデータにアクセスできるメンバーVIを迅速に作成します。
    メモ  このオプションを使用する前に新しいLabVIEWクラスを保存する必要があります。新しいクラスが保存されていないと、データメンバーアクセスのためのVIは無効になります。
  • 新規→オーバーライドのためのVI―先祖メンバーVIをオーバーライドするメンバーVIを作成します。先祖VIアイコンを使用し、新規VIのアイコンを作成する子クラスのアイコンマスクをオーバーレイします。
    メモ  新規→オーバーライドのためのVIオプションは、オーバーライドできる有効なメンバーVIがない場合は無効になります。ダイナミックVIとオーバーライドの詳細については、継承のセクションを参照してください。

フロントパネルまたはブロックダイアグラムのクラス定数、制御器、または表示器を右クリックして、ショートカットメニューからクラスライブラリを表示を選択してプロジェクトエクスプローラウィンドウのクラスをハイライトします。作業中のクラスがLabVIEWプロジェクトにない場合、LabVIEWはクラスウィンドウを開いてクラスを表示します。

継承

継承は、既存のクラスを元に新しいクラスを作成することです。新しいLabVIEWクラスを作成し、他のクラスからデータとメンバーVIを継承するよう設定すると、新しいクラスで継承元のクラスのパブリックメンバーVIやプロテクトメンバーVIを使用できますさらに、新しいデータやメンバーVIを追加して機能を拡張することもできます。たとえば、Vehicleクラスのプライベートデータにはギアの数ドアの数メーカーモデルがあります。Truckという新しいクラスを作成した場合、このクラスをVehicleクラスからのデータを継承するよう設定し、さらにショートベッド?および四駆?などのブール値を追加できます。ただし、以下の図に示すとおり、LabVIEWクラスをバンドルまたはバンドル解除すると、ノードでは現在のクラスのプライベートデータの端子のみが表示されます。先祖クラスから継承されたデータの端子は表示されません。

先祖データはプライベートであり、修正するにはメンバーVIを通して先祖クラスから供給される関数を使用します。派生クラスのメンバーVIは、あらゆるパブリックメンバーVIをLabVIEWのVIと同様に呼び出します。ただし、派生クラスのメンバーVIは先祖クラスのプロテクトメンバーVIを呼び出すこともできます。先祖メンバーVIをプロテクトとして指定すると、すべての子クラスのメンバーVIはメソッドを呼び出せますが、継承階層の外にあるVIはメソッドを呼び出せません。Truckクラス内のVehicleクラスのギアの数にアクセスするには、VehicleクラスにGet Gears.viという名前のパブリックまたはプロテクトメンバーVIを作成します。Get Gears.viのブロックダイアグラムでVehicleクラスをバンドル解除して、ギアの数にアクセスできるようにします。さらに、コネクタペーンでギアの数を出力端子に割り当てて、派生クラス(Truckクラスなど)からVehicleクラスの特定のプライベートデータにアクセスできるようにすることができます。

また、VehicleクラスにデータメンバーにアクセスするメンバーVIを作成してギアの数にアクセスすることもできます。メンバーVIを作成する際は、アクセサを作成ダイアログボックスでプロパティノードを通して使用できるようにするチェックボックスをオンにします。これにより、Truckクラスをプロパティノードに配線し、プロパティ端子を右クリックしてプロパティを選択→ギアの数を選択できるようになります。

メモ  LabVIEWクラスは、別のLabVIEWクラス(親クラスも含む)のプライベートメンバーVIを呼び出すことはできません。プライベートメンバーVIは、同じクラスに属している別のメンバーVIのブロックダイアグラムでのみ使用できます。
メモ  (FPGAモジュール) FPGA VIを作成するときは、一定の制約下で継承を使用できます。

LabVIEWオブジェクト

「LabVIEWオブジェクト」とは、特定のクラスの名前です。LabVIEWのオブジェクト指向プログラミングでは、LabVIEWオブジェクト継承ツリーの最初の先祖となります。デフォルトでは、すべてのLabVIEWクラスはLabVIEWオブジェクトを継承します。LabVIEWオブジェクトを使用して、複数のLabVIEWクラスに対して一般的な操作を実行するVIを作成できます。たとえば、LabVIEWクラスの配列を作成する場合、配列のデータは、配列のクラスタイプの要素や、あらゆる派生クラスの要素で構成されるため統一性がありません。配列のタイプがLabVIEWオブジェクトである場合、Vehicle、Truck、Bowling Ballなどが含まれる可能性があります。Bowling Ballクラスは、VehicleクラスやTruckクラスから継承されたものではないため、最も共通する先祖ベースクラスの配列(この例ではLabVIEWオブジェクト)がダイナミックに作成されます。

以下の図は、Vehicleの配列を表しています。この配列には、VehicleクラスとTruckクラスがあります。TruckはVehicleから継承されるため、この配列の共通の先祖ベースクラスはVehicleタイプです。以下の図には、LabVIEWオブジェクトの配列も表示されています。この配列には、LabVIEWオブジェクト、Vehicle、Truck、Bowling Ballが含まれています。Bowling BallはVehicleまたはTruckから継承されませんが、これらは究極的にはすべてLabVIEWオブジェクトから継承されるため、LabVIEWオブジェクトの配列はLabVIEWオブジェクトタイプです。

継承を設定する

デフォルトでは、すべてのLabVIEWクラスはLabVIEWオブジェクトを継承します。別のクラスの継承元となるクラスを変更するには、そのクラスを作成した後に継承を変更する必要があります。クラスの継承やその他の設定は、クラスプロパティダイアログボックスで行います。LabVIEWクラス階層ウィンドウにLabVIEWクラスの階層を表示することができます。クラスの継承階層には以下のクラスタイプが含まれます。

  • 親クラス―他のLabVIEWクラスによってデータ、パブリックメンバーVI、プロテクトメンバーVIが継承されるLabVIEWクラス。
  • 子クラス―親クラスのパブリックメンバーVIおよびプロテクトメンバーVIを継承するLabVIEWクラス。子クラスは親クラスがアクセサVIを提供しない限り、プライベートデータを継承しません。
  • 兄弟クラス―他のLabVIEWクラスと同じ親クラスを共有するLabVIEWクラス。
  • 先祖クラス―1つのLabVIEWクラスの親クラス、2世代上のクラス、3世代上のクラスにあたるLabVIEWクラス。LabVIEWオブジェクトは、すべてのLabVIEWクラスの究極的な先祖です。
  • 派生クラス―1つのLabVIEWクラスの子クラス、2世代下のクラス、3世代下のクラスにあたるLabVIEWクラス。
メモ  親クラスのプロパティアクセサVIがVIによりオーバーライドされる場合、子クラスおよび親クラス両方のプロパティ定義フォルダで名前およびフォルダパスが同じである必要があります。

ワイヤの外観

クラスは新しいデータタイプを定義します。ブロックダイアグラムには、クラスのワイヤは、デフォルトのLabVIEWクラスワイヤの外観で表示されるか、親クラスのワイヤの外観を継承します。LabVIEWクラスのワイヤの外観の変更は、クラスプロパティダイアログボックスで行います。分かりやすいブロックダイアグラムを作成するために、各LabVIEWクラスのワイヤの外観を必要に応じて変更することができます。ワイヤの色やパターンを過度に多様化すると、ブロックダイアグラムがかえって分かりにくくなる場合があります。以下の図では、左側にLabVIEWの標準のワイヤの外観、右側にカスタマイズされたワイヤの外観の例を示しています。

LabVIEWで過度のワイヤパターンと色の作成を回避する方法の詳細ヒントについては、「LabVIEWスタイルチェックリスト」を参照してください。

ダイナミック/スタティックディスパッチメンバーVI

メソッドは、実行する操作、またはオブジェクトによる操作です。LabVIEWのオブジェクト指向プログラミングでは、メンバーVIがメソッドとなります。メンバーVIは、LabVIEWクラスのデータに対して操作を実行します。1つのVIで、複数のメソッドを定義できます。これら複数のメソッドは、常に同じVIの呼び出しによって実行されるため「スタティックディスパッチメソッド」と呼ばれます。メソッドはクラス階層全体で同じ名前を持つ複数のVIを使用して定義することもできます。これらのメソッドは、LabVIEWによってどのVIセットが呼び出されるかが実行されるまで不明なため、「ダイナミックディスパッチメソッド」と呼ばれます。ダイナミックディスパッチメソッドは、多態性VIに類似しています。多態性VIが配線されたデータタイプに応じて呼び出すVIを決定するのに対し、ダイナミックディスパッチメソッドは、実行時に入力端子に入力されるデータに応じてクラス階層内の呼び出すメンバーVIを決定します。

メンバーVIをスタティックまたはダイナミックに指定するには、そのメンバーVIのコネクタペーンを使用します。コネクタペーンにダイナミックディスパッチ入力端子が含まれる場合は、メンバーVIはダイナミックディスパッチメソッドの一部です。ダイナミック入力端子を持たないメンバーVIは、スタティックディスパッチメソッドです。

1つのLabVIEWクラスが別のLabVIEWクラスを継承する場合、この子クラスは親クラスで定義されているすべてのパブリックメソッドとプロテクトメソッドを継承します。子クラスのメンバーVIに親クラスのメンバーVIと同一の名前を付けると、メソッドの子の実装を定義することになります。

スタティックディスパッチメソッドは1つのVIで定義されるため、子クラスのメンバーVIに先祖クラスのスタティックディスパッチメンバーVIと同じ名前を付けないでください。たとえば、親クラスのVehicleにはスタティックディスパッチメンバーVIであるOpen Door VIが含まれるため、子クラスのTruckはOpen Door VIという名前のメンバーVIを持つことはできません。Open Door VIのメソッドは、TruckがVehicleからメンバーVIを継承するため、すでにTruckで定義されています。ブロックダイアグラムにスタティックディスパッチメンバーVIをサブVIとして配置すると、これらのメソッドは通常のサブVIを呼び出した場合と同様に動作します。

複数のダイナミックディスパッチVIを1つのメソッドとして定義できます。このとき、各VIを継承階層の異なるレベルに作成します。ダイナミックディスパッチVIが親クラスで定義されており、そのVIを子クラスでも定義すると、子クラスの実装によって親クラスの実装がオーバーライドまたは拡張されます。以下の例では、VehicleクラスとTruckクラスがどちらもSet Make.viというダイナミックディスパッチメソッドの実装を定義しています。ダイナミックディスパッチVIをブロックダイアグラムにサブVIとして配置すると、ブロックダイアグラムのノードはLabVIEWの編集モードで通常のサブVIを呼び出した場合と同様に動作します。ただし、VIを実行するとダイナミックディスパッチ入力端子で受信されるデータにより、LabVIEWによって呼び出されるクラス階層のダイナミックメンバーVIの実装が決定されます。LabVIEWクラスのワイヤは、そのLabVIEWクラスのタイプまたは子のタイプのデータを送るため、ノードはそのクラスデータに対して定義されたダイナミックディスパッチVIの実装を実行します。以下の例を再度確認してください。Set Make VIのVehicleクラス実装のみが、Main VIのブロックダイアグラム上にあります。ループの最初の反復では、Vehicleクラスのデータがクラスワイヤ上にあるため、LabVIEWではSet Make VIのVehicleクラスの実装を実行します。ループの2番目の反復では、Truckクラスのデータがクラスワイヤ上にあるため、LabVIEWではSet Make VIのTruckクラスの実装を実行します。

親クラスがダイナミックディスパッチVIを定義し、そのVIの実装を行わない場合は、各子クラスが親VIをオーバーライドする必要があります。多くの場合、親クラスVIで意味のある動作をすることは不可能です。たとえば、Area VIを定義するShapeクラスがあるとします。Area VIはShapeオブジェクトに形状の領域を返します。すべてまたは大部分の形状に使用できる領域を計算する1つの式というものはありません。そのため、各派生クラスはArea VIをその形状に対応する式でオーバーライドする必要があります。子クラスのCircleを作成する場合、Circleクラスはpi * radius * radiusを計算するArea VIを提供する必要があります。

親クラスVIの実行を定義しない場合は、親VIはすべてのオーバーライドVIが一致する必要があるコネクタペーンとVIプロパティの定義にすぎません。各子クラスはそのようなオーバーライドVIを提供する必要があります。この条件が必ず強制されるように、親クラスのVIを、各子クラスがオーバーライドしてLabVIEWが要件を強制するようマークすることができます。

一部の子クラスは、メンバーVIの機能をオーバーライドできない場合があります。たとえば、QuadrilateralクラスがShapeクラスの子である場合、特定の種類の四角形を知らない限り、領域に正しい式を提供できません。Quadrilateralクラス内にArea VIの空の実行を作成しないように、Quadrilateralクラス自身の子クラスにオーバーライド条件を転送するようにQuadrilateralクラスに指示することができます。これを実行するには、子クラスを右クリックして、ショートカットメニューからプロパティを選択し、プロパティダイアログボックスを表示します。継承ページで、派生クラスにすべてのオーバーライド条件を転送チェックボックスをオンにします。これにより、LabVIEWは、Quadrilateralクラスの子クラスであるTrapezoidやRectangleにArea VIをオーバーライドすることを要求します。

派生クラスが親クラスメンバーVIをオーバーライドする条件による、メンバーVIの動作方法への影響はありません。

メモ  LLBに同じ名前のファイルを追加することはできません。したがって、1つのクラス階層内に同じ名前のダイナミックメンバーVIがある場合、これらのクラスを同じLLBに追加できません。

メモ  子クラスのVIが親クラスのVIを無効にする場合、子のVIは、その再入可能設定推奨する実行設定優先度設定、コネクタペーン端子、コネクタペーンパターン、アクセススコープが親VIのものと一致している必要があります。

ブロックダイアグラムのダイナミックディスパッチサブVIをダブルクリックし、実装を選択ダイアログボックスを表示します。このダイアログボックスで、現在メモリの常駐するダイナミックディスパッチサブVIのすべての実装を表示し、このサブVIの1つ以上の実装を開きます

新規→オーバーライドのためのVIを選択してダイナミックディスパッチメンバーVIの先祖となる実装をオーバーライドするVIを作成すると、新しいダイナミックディスパッチメンバーVIが作成されます。これは、オーバーライドするVIが、オーバーライドされる先祖のメンバーVIと同じ名前で、またダイナミックディスパッチ端子を持つためです。VIのブロックダイアグラムには、オーバーライドされる上位のVIと一致するように、適切なダイナミックディスパッチ入出力クラス端子とその他の端子を持つ親メソッド呼び出しノードが配置されます。オーバーライドできる先祖メンバーVIがない場合はオーバーライドのためのVIオプションが無効になります。

メモ  (FPGAモジュール) FPGA VIを作成するときは、一定の制約下でダイナミックディスパッチを使用できます。

ダイナミックディスパッチ出力

LabVIEWクラス出力端子をダイナミックに設定するには、コネクタペーンの出力端子を右クリックしてダイナミックディスパッチ出力(推奨)を選択します。ダイナミックディスパッチ出力端子を持つVIをサブVIとして呼び出すと、ダイナミックディスパッチ出力のデータタイプが、ダイナミックディスパッチ入力端子に接続されているワイヤと同じになります。たとえば、Vehicleクラスのワイヤをダイナミックディスパッチ入力端子に接続すると、メンバーVIの出力のデータタイプが入力と同じVehicleクラスになります。ダイナミックディスパッチ入力端子とダイナミックディスパッチ出力端子の間のデータは変更できます。ただし、LabVIEWクラスの実行を保証するため、ダイナミックディスパッチ入力端子からのデータはすべてのダイナミックディスパッチ出力端子に渡されなければなりません。また、必ずダイナミックディスパッチ入力端子が一度だけ読み取られ、ダイナミックディスパッチ出力端子が一度だけ書き込まれるようにするために、ダイナミックディスパッチブロックダイアグラム端子はストラクチャ内に配置できません。

メモ  ダイナミックディスパッチ入出力を持つダイナミックディスパッチメンバーVIをデバッグする場合、ダイナミックディスパッチ入力からダイナミックディスパッチ出力へのワイヤでエラーが発生していないか確認できます。ダイナミック入力で始まり、ランタイムデータタイプを変更する可能性がある関数を通過しないワイヤの背景色は、デフォルトの白ではなくグレーで表示されます。データタイプを変更する可能性がある関数を通過するワイヤの背景色は赤で表示されます。ダイナミック出力を正しく動作させるために、LabVIEWクラスのデータタイプは変更できません。

LabVIEWクラスの出力データタイプが入力データタイプと異なることが既に分かっているメンバーVIのブロックダイアグラムを実行するには、LabVIEWクラスのコネクタペーンのダイナミック出力端子をダイナミックディスパッチ出力(推奨)ではなく推奨に設定します。たとえば、入力がVehicleクラスであるLabVIEWクラスの出力をTruckクラスにするには、LabVIEWクラスのコネクタペーンでデフォルト端子を変更する必要があります。または、ブランクVIからメンバーVIを作成して、コネクタペーンを手動で設定することもできます。

メモ  ダイナミックディスパッチ入力とダイナミックディスパッチ出力を持つメンバーVIでケースまたはイベントストラクチャを使用する場合は、出力トンネルで配線されていない場合、デフォルトを使用を選択できません。出力トンネルで配線されていない場合、デフォルトを使用を出力トンネルで使用すると、VIが破損します。ストラクチャですべてのケースを配線する必要があります。自動的に入力トンネルと出力トンネルを配線するようにトンネルを構成することを検討してください。

ダイナミックディスパッチのメモリコピーの最適化

上記のとおり、ダイナミックディスパッチメソッドを作成する場合、各子クラスは親クラスで定義されたすべてのパブリックメソッドとプロテクトメソッドを継承します。子クラスは、独自のバージョンを持つこれらのメンバーVIを無効または拡張できます。VIがダイナミックディスパッチメソッドを呼び出す場合、実行時まで、呼び出すメソッドのバージョンはわかりません。そのため、発呼者VIのメモリ割り当ては、子クラスにあるすべてのメンバーVIは親クラスにあるメンバーVIと同じ条件で設定されていると仮定し、最適化が行われます。入力が親VIの定数の場合、発呼者VIは、すべての子VIで定数になるとみなされます。入力が親クラスのメンバーVIで出力として返される場合、発呼者VIは、すべての子クラスのメンバーVIと同じになるとみなされます。

これらの推測が間違っている場合、最適化は失われます。たとえば、不変の入力を持つメンバーVIを作成した場合、発呼者VIは、オーバーライドによって必ず入力の一部またはすべてが変更される可能性があるにもかかわらず、入力がまったく変更されないと想定します。また、親クラスのメンバーVIで出力に対して1つも入力を配線しないと、発呼者VIは、後続のメンバーVIでは出力に対して入力が配線されている可能性があるにもかかわらず、出力が入力とメモリをまったく共有しないと想定します。このような場合、子クラスの予期しない動作を処理するコードの作成が必要となり、最適化が損なわれます。

より良い最適化のために、子クラスVIで発生すると想定される動作に一致する親クラスVIを作成することができます。このためには、たとえばダイナミックディスパッチメソッドを作成して、各端子の予想される動作はIn Place要素ストラクチャを使用することであると明確に示すことができます。親クラス内のダイナミックディスパッチVIの内部にIn Place要素ストラクチャを配置し、In Place要素ノードペアをIn Place要素ストラクチャに追加します。これらのノードペアを使用し、出力に接続する入力、定数として処理する入力、変更する入力を表すことができます。これで、発呼者VIを最適化できるようになります。

ダイナミックディスパッチ端子を使用したサンプルについては、以下のプロジェクトを参照してください。

  • labview\examples\Object-Oriented Programming\Dynamic Dispatching\Dynamic Dispatching.lvproj

  • labview\examples\Object-Oriented Programming\Dynamic Terminals\Dynamic Terminals.lvproj



この記事は役に立ちましたか。

役に立たなかった