Win32API関数を使用する

 今まで.NET Frameworkの話をしていて、ちょっと脱線しますが、Iron PythonからWin32API関数を使用する方法を説明します。

 アセンブリモジュールを作る

 残念ながらIron PythonにはWin32APIを直接扱う仕組みを持っていません。ですがC#にはWin32APIを扱える仕組みがあります。なので、C#の力を借りてWin32API関数を利用するのが一番手っ取り早いです。
 C#のVisual C# 2010 Expressを使って、クラスライブラリ作成のソリューションを新規で作ります。これを使うとアセンブリモジュール(.NET版DLL)が作れます。今回はソリューション名を”MyDLL"にしました。自動で作成されるcsファイルは"class1.cs"だと思いますが味気ないので、"Win32Beep.cs"に名前を変更して内容を次のようにします。

using System;
using System.Runtime.InteropServices;

namespace MyDLL
{
  public class Win32Beep {
    [DllImport("kernel32.dll")]
    public extern static bool Beep(uint dwFreq, uint dwDuration);
    
  }
}

 私も正直C#のことは勉強不足でよくわかりませんが、多分DllImportの後に呼び出したいWin32API関数が入っているDll名を書いて、その後に使いたいWin32API関数を記述すればいいんだと思います。

 ここでポイントが最後の行です。
 public⇒C#の記述では大抵"static"になってますが、Dllファイル内部で使用するわけではないので、Iron Pythonが使用できるように"public"にします。
 extern⇒これはWin32API関数がcsファイルの中で記述されていないことを宣言しています。
 static⇒これはcsファイルからDllファイルを作成するとき、Win32API関数の中身をDLLファイルの中に入れて一緒にしちゃうという意味で書かれています。

 上記の重要な単語の後で目的のWin32API関数を記述します。今回はBeep関数を例に挙げました。本当はもっと難しいこともあるんですが、でも大体こんな理解でも動かせます。難しいことは他の資料をあたってください。

 それで『F6』キーを押してしまえば、Beep関数のことが書かれた"MyDLL.dll"が完成します。次にこのアセンブリモジュールをIron Pythonで使うところを説明します。

 アセンブリモジュールをimportする。

 まず出来上がった"MyDLL.dll"をIron Pythonのスクリプトファイルrがあるフォルダに移動します。そしてアセンプリモジュールをimportするためにスクリプトには例えば次のように記述します。

import clr
clr.AddReferenceToFile("MyDLL.dll")

import MyDLL
from MyDLL.Win32Beep import Beep

 clr.AddReferenceToFileメゾットでアセンプリモジュールをIron Pythonに教えてあげ、MyDLL.Win32BeepのBeep関数をimportすれば、Beep関数は使用できるようになります。

 Beep関数で遊んでみる

ではBeep関数を使って、ちょっと遊んでみましょう。

import System
from System.Threading.Thread import Sleep

import clr
clr.AddReferenceToFile("MyDLL.dll")

import MyDLL
from MyDLL.Win32Beep import Beep
#ド
Beep(262,750)
Beep(294,250)
Beep(330,750)
Beep(262,250)
Beep(330,500)
Beep(262,500)
Beep(330,1000)
#レ
Beep(294,750)
Beep(330,250)
Beep(349,250)
Beep(349,250)
Beep(330,250)
Beep(294,250)
Beep(349,1000)
Beep(349,1000)
#ミ
Beep(330,750)
Beep(349,250)
Beep(392,750)
Beep(330,250)
Beep(392,500)
Beep(330,500)
Beep(392,1000)
#ファ
Beep(349,750)
Beep(392,250)
Beep(440,250)
Beep(440,250)
Beep(392,250)
Beep(349,250)
Beep(440,1000)
Beep(440,1000)
#ソ
Beep(392,750)
Beep(262,250)
Beep(294,250)
Beep(330,250)
Beep(349,250)
Beep(392,250)
Beep(440,1000)
Beep(440,500)
Sleep(500)
#ラ
Beep(440,750)
Beep(294,250)
Beep(330,250)
Beep(349,250)
Beep(392,250)
Beep(440,250)
Beep(494,1000)
Beep(494,500)
Sleep(500)
#シ
Beep(494,750)
Beep(330,250)
Beep(349,250)
Beep(392,250)
Beep(440,250)
Beep(494,250)
Beep(523,1000)
Beep(523,500)
#End
Beep(523,250)
Beep(494,250)
Beep(440,500)
Beep(349,500)
Beep(494,500)
Beep(392,500)
Beep(523,1000)
Beep(523,500)

 上のスクリプトはインデントがないので、コピペすればすぐに実行できると思います。ぜひ実行してみてください(笑)。