プロデルで始める日本語プログラミング言語入門(#21).NETを駆使してパワーアップしよう

連載プロデル入門の21話目です。今回は、プロデルのネット型を使って.NET Frameworkのクラスを呼び出す方法を紹介します。プロデル専用のライブラリでは実現できないことをプロデルで実現したいという時に必要な用語や機能をご紹介します。

ネット型が必要になるとき

プロデルは、.NET Framework上で構築されています。プロデルでは.NET Frameworkで使える機能のうちで、アプリ作りによく使われる機能に絞って日本語プログラミング向けにアレンジして用意しています。そのため、.NETで使えてもプロデルで用意されていない機能もあります。これらの機能を利用するための手段として、ネット型が用意されています。

なお、プロデルでは、.NET Frameworkの機能に、日本語プログラミング言語に適した名前や属性(助詞など)を付けて、日本語で実行できるようにしていますが、ネット型では日本語プログラミング向けに整理されていないため、助詞などを使って日本語で利用することはできません。

.NET固有の言葉と概念

プロデルから.NETのクラスライブラリを利用するにあたって、最初に.NET型に関連する主な用語を簡単にご説明します。なお正確な説明は.NETの公式ドキュメントをご参照ください。

クラスライブラリ(FCL)

.NET Frameworkで標準で提供されている機能群を「クラスライブラリ」と呼びます。.NETでは必要な機能がクラス単位で用意されていて、それらがライブラリとしてまとめられています。クラスライブラリは、.NET Frameworkをインストールすると実行環境と共にインストールされます。

アセンブリ

クラスライブラリのうちで、特定の機能ごとにクラスをまとめたモジュールのことを「アセンブリ」と呼びます。プロデルでは「プラグイン」と呼んでいるものです。一つのアセンブリは、一つのファイル(dllもしくはexe)として管理されています。また、アセンブリのうち標準的なアセンブリは、GACと呼ばれる場所に登録されていて、完全名を指定すれば、dllファイルを指定しなくても、利用できるアセンブリもあります。

クラス

プロデルでは「種類」に相当するものです。クラスにはメンバーとしてメソッド,プロパティ,フィールド,イベントといった定義が含まれています。

名前空間

クラスの分類したまとまりを表す名前のことを「名前空間」と呼びます。アセンブリは物理的なファイルのまとまりですが、名前空間は論理的なまとまりです。そのため、複数のアセンブリで同じ名前空間を使われることもあります。

プロデルで.NETのクラスを指定する場合には、基本的に完全なクラス名を指定します。完全なクラス名は「名前空間.クラス名」の形式で指定します。例えば「System.Windows.Forms.Button」という完全なクラス名では「System.Windows.Forms」が名前空間で、「Button」がクラス名です。

メソッド, プロパティ, フィールド, イベント

クラスに含まれる宣言要素です。メソッドは手順に相当し、プロパティは設定項目に相当します。さらに、フィールドは種類変数、イベントはイベント手順に相当します。クラスをインスタンス化してから使うメンバーと、インスタンス化せすにそのまま使える静的メンバーとがあります。

なおプロデルの手順には、日本語で扱いやすいように助詞などの属性が付与されていますが、.NETのメソッドには属性が付与されていません。そのため、手順のように助詞を使って呼び出すことはできません。

これらの用語の関係を図にすると次のようになります。

プロデルは、.NETの設計思想の上に、日本語で記述するための様々な属性を付与して構築されています。プロデルでは両者を別々に管理しているため、.NETのクラスとプロデルの種類とで扱いが異なる部分があります。

.NETのクラスを使う方法

プロデルで.NETのクラスライブラリを利用するには、アセンブリをプロデルで利用できるようにします。そして、ネット型のクラスからインスタンス(オブジェクト)を作ってメンバー(メソッドやプロパティ)を利用します。

ネット型

プロデルでは、.NETのクラスを「ネット型」と呼びます。

1. アセンブリの参照 (利用する文)

まず利用したい.NETのクラスが含まれるアセンブリを参照する必要があります。プロデルでは「ネット型として利用する」文で、アセンブリの参照を利用できるようにします。アセンブリを参照するための「利用する」文の例文は次の通りです。

「System.Windows.Forms」をネット型として利用する
「System.Drawing」をネット型として利用する
「assembly.dll」をネット型として利用する

利用する文では、アセンブリ完全名か、アセンブリのファイルがあるパスを指定します。C#などで標準的に利用できるアセンブリの場合、アセンブリの名前を指定すれば利用できます。一方、標準でない外部のライブラリを利用する場合には、DLLの場所をフルパスで指定します。

2.ネット型のインスタンスを作る

プロデルでは、純粋な.NET(FCL)の型を「ネット型」と呼びます。ネット型を使うには、次のような書式で書きます。

"【クラス名】"のネット型を作る

クラス名には、名前空間を含むクラス名を指定します。C#では、usingキーワードで名前空間を指定することで名前空間を省略できますが、プロデルでは名前空間も指定します。

ネット型から作ったオブジェクトは、.NETのクラスに準じたオブジェクトであるため、そのクラスに定義されたメソッドやプロパティなどを操作できます。

「System.Windows.Forms」をネット型として利用する
ボタンとして"System.Windows.Forms.Button"のネット型を作る

引数を持つコンストラクタでは、型名に続けて( )の中に引数を指定します。引数を複数指定する場合には、カンマ(,)で区切って指定します。

builderという"System.Text.StringBuilder"のネット型(256)を作る

完全名で指定する場合

また、ネット型は、完全修飾型名で指定することもできます。「利用する」でアセンブリを参照している場合には完全修飾型名で指定する必要はありません。

"【完全なクラス名】,【アセンブリ名】"のネット型を作る
"System.Windows.Forms.Button, System.Windows.Forms"のネット型を作る

メソッド呼び出し

ネット型のオブジェクトのメソッドを呼び出すには、次のような書式で書きます。

【オブジェクト名】:【メソッド名】(引数)

C#やVB.NETでは「.」と書くべきところを、プロデルでは「:」で指定します。「:」はプロデル上でレシーバオブジェクトを表す記号です。引数には、メソッドに渡す値を指定します。複数の引数を指定するときには「,」で区切ります。また引数が必要ないメソッドでは省略することができます。ネット型のメソッドでは助詞は指定できません。

builderという"System.Text.StringBuilder"のネット型を作る
builder:Append(「こんにちは」)

プロパティ/フィールドへの取得と設定

プロパティの操作は設定項目とほぼ同じ扱いとなります。プロデルからプロパティの値を取得したり設定したりするには、次のような書式で書きます。

【オブジェクト名】の【メソッド名】

C#やVB.NETでは「.」と書くところを、プロデルでは「の」を使います。またフィールドも同様に「の」を使って操作できます。

プロパティから値の取得

設定項目へ設定するときと同じように、設定項目アクセス式で指定できます。

(builderのLength)を表示する

プロパティ/フィールドへ値の設定

代入文で設定、代入できます。

builderのCapacityは、256

静的メソッド, 静的プロパティへの操作

インスタンスを作らずに操作できるメンバー(メソッド,プロパティ,フィールド変数)のことを「静的メンバー」と呼びます。

静的メソッドを操作するには、ネット型に対して静的参照を表す「!」をレシーバに指定します。

["System.String"のネット型!:Concat(「A」,「B」)]を表示する

静的プロパティを操作するには、ネット型に対して静的参照を表す「!」を設定項目のアクセス式に指定します。

"System.DateTime"のネット型!のNowを表示する

列挙型の値

プロパティやメソッドの引数によっては列挙型の定数値を指定する場合があります。プロデルでは列挙型の定数名を文字列で指定します。なお、一部の列挙型はプロデルで対応する列挙型が定義されていますので、その場合は対応するプロデルの日本語名の列挙型の定数名を指定します。

※対応するネット型と対応する列挙型は今後マニュアルに記載する予定です

イベントハンドラの設定

プロデルでは、イベントがイベント手順と同じ機能ですので、イベント手順を設定する代入文で指定します。オブジェクトのイベントを手順で受け取るには、次のような書式でイベントハンドラとして手順を指定します。

【オブジェクト名】の【イベント名】時の手順は、【呼び出す手順】

イベントが発生した時の引数(C#一般に変数名eと付けられる引数)は「この時」特殊変数に保存されます。「この時」特殊変数もネット型のオブジェクトとして操作できます。

ボタンのClick時の手順は、クリックさせた
窓のClosed時の手順は、閉じられた

値の型変換

文字列(string型)や整数(int型)、PointやSizeなどよく使われるクラスや構造体は、プロデルの型と対応付けられています。そのため、ネット型のメソッドの引数や戻り値、プロパティ、フィールドの型がネット型であっても、対応するプロデルの型と、適切なネット型とで相互に変換されます。

対応付けられている主なクラスと種類は、マニュアル(.NETクラスと対応する種類)に記載しています。

ネット型に対応した種類

ネット型では、種類で「対応する」を指定することで、そのネット型に対応するプロデルの種類を定義できます。特定のネット型と種類とが1対1で対応しています。「継承する」と異なる点は「対応する」で指定したネット型のオブジェクトが自動的にその種類へ型変換される点です。

ネット型のクラスに対応した種類として定義して、さらに手順や設定項目を日本語名で定義すれば、ネット型のメソッドやプロパティを、日本語で書けるようにも工夫できます。

ドットフォームとは
	"System.Windows.Forms.Form"のネット型に対応する
	タイトルという属性
		取得する手順
			継承元のTextを返す
		終わり
		設定する手順
			継承元のTextは、設定値
		終わり
	終わり
終わり

プログラム例

ネット型を使ってクラスライブラリのクラスを利用する例を掲載します。プログラムの操作は、C#やVB.NETと同じですが、プロデルの手順呼出し文と設定項目の式に則ってメソッドやプロパティを操作していきます。

StringBuilderクラスによる文字列の連結

一つ目は、StringBuilderクラスのインスタンスを生成して操作するプログラムです。StringBuilderのネット型からオブジェクトを作って、AppendメソッドやLengthプロパティを操作します。

builderという"System.Text.StringBuilder"のネット型を作る
builder:Append(「こんにちは」)
builder:Append(「さようなら」)
「[builderのLength]:[builder:ToString()]」を表示する

StreamReaderクラスを使って一文字ずつ出力する

2つ目は、ファイルの内容を読み取るStreamReaderクラスを使って、ShiftJIS形式のファイルの内容を一文字ずつ取り出すプログラムです。静的メソッドであるEncoding.GetEncodingメソッドを操作するために「!」で静的な種類として参照しています。

シフトジスは"System.Text.Encoding"のネット型!:GetEncoding(「shift_jis」)
リーダは"System.IO.StreamReader"のネット型(「テキスト.txt」, シフトジス)を作る
(リーダ:Peek())が-1より大きい間繰り返す
	["System.Convert"のネット型!:ToChar(リーダ:Read())]を報告する
そして
リーダ:Close()

FormにButtonを配置する

3つ目に、Windowsフォームでボタンを配置するプログラムです。FormクラスとButtonクラスをそれぞれ対応する種類として定義しておき、その種類を作ってネット型のメソッドやプロパティを操作します。ここでは、設定項目を定義して、Textプロパティを「見出し」設定項目として操作できるようにします。

フォームデザイナが使えないため、Visual Studio上のC#で書く場合とも勝手が違いますが、一応フォームを表示させることができます。なお、Size型やPoint型、フォーム関連の一部の列挙型は、プロデルの標準の型に自動的に変換される仕組みになっています。

また、プロデルデザイナ上でのプログラムは、UIとは別スレッドで実行されているため、明示的にUIスレッドで実行させる必要があります。(プロデルの種類では自動的にUIスレッドで実行されます)

「System.Windows.Forms」をネット型として利用する
UIスレッドで『
	窓というドットフォームを作る
	ボタンというドットボタンを作る
	窓のTextは「WinFormsのテスト」
	窓のFormBorderStyleは「固定ツール」
	ボタンのLocationは{30,30}
	ボタンのSizeは{126,40}
	ボタンの見出しは「メッセージ」
	ボタン:Show()
	窓のControls:Add(ボタン)
	窓:Show()
』を実行する
ボタンのClick時の手順は、クリックさせた
窓のClosed時の手順は、閉じられた
待機する

クリックさせた手順
	「こんにちは」を表示する
終わり
閉じられた手順
	終了する
終わり

ドットフォームとは
	"System.Windows.Forms.Form"のネット型に対応する
終わり

ドットボタンとは
	"System.Windows.Forms.Button"のネット型に対応する
	見出しという属性
		取得する手順
			継承元のTextを返す
		終わり
		設定する手順
			継承元のTextは、設定値
		終わり
	終わり
終わり

NAudio.dllを利用する

.NETではNuGetなどといったパッケージ管理ツールを通じて、たくさんのライブラリが提供されています。ライブラリのdllファイルがあればプロデルからその機能を利用できます。

今回は、.NET向けに提供されている音声を取り扱うためのライブラリ(NAudio.dll)をプロデルから利用する方法を紹介します。

NAudio.dllの最新版は、NuGetで配布されています。NuGetのパッケージのdllをダウンロードするには、dotnetコマンドツールを使って、プロジェクトを作成しビルドして必要なdllファイルを取り出します。

なお、ここで紹介する方法は、.NET 8.0のSDK(開発環境)がインストールされていることを前提としています。NuGetパッケージで提供されているライブラリを利用する場合にはインストールしてください。

コマンドプロンプト(ターミナル)で次のコマンドを連続して入力します。

mkdir naudiotest
cd naudiotest
dotnet new console
dotnet add package NAudio
dotnet build

最後まで実行するとnaudiotestフォルダが作られ、その中の「\bin\Debug\net8.0」フォルダにNAudioに関連するdllファイルがコピーされます。これらのdllファイルをプロデルプログラムと同じフォルダにコピーしてネット型として利用します。

WAV形式の再生

まずはNAudioでWAV形式を再生するプログラムを作ってみます。この例では、NAudio.dll, NAudio.Core.dll, NAudio.Wasapi.dllの3つのアセンブリを使います。またWasapiOutクラスのインスタンス(outputDevice)とWaveFileReaderクラスのインスタンス(wavStream)をそれぞれ作ります。Initメソッドを呼び出すことで、outputDeviceでwavStreamが再生できるように初期化されます。

「NAudio.dll」をネット型として利用する
「NAudio.Wasapi.dll」をネット型として利用する
「NAudio.Core.dll」をネット型として利用する
outputDeviceという"NAudio.Wave.WasapiOut"のネット型を作る
wavStreamという"NAudio.Wave.WaveFileReader"のネット型(「C:\Windows\Media\Alarm05.wav」)を作る
outputDevice:Init(wavStream)
outputDevice:Play()
10秒待つ
outputDevice:Stop()

mp3をWAV形式へ変換する

次にNAudioでmp3形式をWAV形式へ変換するプログラムを作ってみます。「MediaFoundationReader」「WaveFormat」「MediaType」「MediaFoundationEncoder」の4つのクラスのインスタンスを作ります。readerで変換元のメディアを読み込み、formatとmediaTypeで変換先のメディアの種類を指定します。encoderのEncodeメソッドで変換元メディアを変換先のメディアに変換します。

「NAudio.Wasapi.dll」をネット型として利用する
「NAudio.Core.dll」をネット型として利用する
readerという"NAudio.Wave.MediaFoundationReader"のネット型(「bgm.mp3」)を作る
formatという"NAudio.Wave.WaveFormat"のネット型(32000, 16, 1)を作る
mediaTypeという"NAudio.MediaFoundation.MediaType"のネット型(format)を作る
encoderという"MediaFoundationEncoder"のネット型(mediaType)を作る
encoder:Encode(「[デスクトップ]sample.wav」, reader)

まとめ

今回は、プロデルから.NET Frameworkのクラスライブラリを利用する方法を紹介しました。.NETのクラスライブラリを活用するには、実際にはC#のプログラムを読まなければなりませんが、その分、プロデルだけでは実現できないことも実現できます。今回紹介したネット型について理解しなくてもプロデルを十分活用できます。もし.NETやC#言語の知識があれば、必要になった時にプロデルでもご活用ください。

なお.NET関する詳しい説明は、.NETのドキュメントなどをご参照ください。また、.NETで提供される機能を使いたい場合には、あらかじめC#言語を習得することをお勧めします。.NET全般に関するご質問はプロデル掲示板ではお答えできかねますので、ご了承ください。

※当ブログの記事の著作権はゆうとにあります。プロデルに関係が無い目的で、文章や図表,プログラムを複製, 改変, 移植して掲載することを堅く禁止します

  • いいね (2)
  • 続編を読みたい (1)

“プロデルで始める日本語プログラミング言語入門(#21).NETを駆使してパワーアップしよう” への1件の返信

  1. こんにちは。アークです。

    「.NETを駆使してパワーアップしよう」の記事、ありがとうございます。
    また、「お知らせ」がホームページに表示されるようになったのも有難いです。

    待ち望んでいた.NETの記事を先ずは流し読みしてみました。
    「矢張り手強そう」というのが率直な感想です。
    下記は現在の理解度です。

     クラスライブラリ (FCL) …………………………… 問題なし
     アセンブリ ………………………………………… 了解です
     クラス ………………………………………… 問題なし
     名前空間 ……………………………………………… 概念は苦手です
     メソッド, プロパティ, フィールド, イベント ……… 了解です
     
     1. アセンブリの参照 (利用する文) ……………… 了解です
     2.ネット型のインスタンスを作る ………………… 了解です
     メソッド呼び出し ……………………………… 了解です
     プロパティ/フィールドへの取得と設定 ………… 了解です
     静的メソッド, 静的プロパティへの利用 ……… 「静的」とは?
     列挙型の値 ……………………………………… 了解です
      ※対応するネット型と対応する列挙型は今後マニュアルに記載する予定です … 助かります
     イベントハンドラの設定 ………………………… 問題なし
     値の型変換 ……………………………………… 了解です
     ネット型に対応した種類 ………………………… 了解です
     
    これ以降に続く「プログラム例」が参考になります。
    この様なサンプルを多数履修する事で理解が深まると思っています。
    アルファチャンネル関係などの続編を期待しています。

コメントを残す