Hatena::Groupperl

Perl Tech RSSフィード

2006-07-22

Perl.NET Frameworkを使う はてなブックマーク -  Perlで.NET Frameworkを使う - Perl Tech

色々試した結果,XSで.NET Frameworkの呼び出しに成功したので報告する。このトリックMicrosoft Visual C++ 2005のC++/CLIという言語を利用することで実現している。これを使えばWideStudioやwxWidgetsのようなGUIライブラリが不要になる上,日本語処理もうまく動作する。動的にライブラリを呼び出し出来れば言うこと無しだが,現状はクラスごとにXSを書くしかないだろう。

テスト環境

XSの作成

コマンドプロンプトでh2xs -A --skip-exporter -n CLRと入力する。これでXSの骨組みが作成される。次に同じディレクトリCLR.hというファイルを作り,以下のように入力する。文字コードUTF-8にする。

#using "System.dll"
#using "System.Data.dll"
#using "System.Drawing.dll"
#using "System.Windows.Forms.dll"

namespace CLR {
  using namespace System;
  using namespace System::Windows::Forms;

  void run() {
    Console::WriteLine("Hello, CLR\n");
    MessageBox::Show("メッセージ(UTF-8)");
    Application::Run( gcnew System::Windows::Forms::Form() );
  }
}

CLR.xsを以下のように編集する。

#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"
#include "CLR.h"

MODULE = CLR		PACKAGE = CLR

void
hello()
    CODE:
        CLR::run();

さらに,Makefile.PLを以下のように編集する。(面倒なのでパス等は直接記入している)

use 5.008008;
use ExtUtils::MakeMaker;
# See lib/ExtUtils/MakeMaker.pm for details of how to influence
# the contents of the Makefile that is written.
WriteMakefile(
    NAME              => 'CLR',
    VERSION_FROM      => 'lib/CLR.pm',
    PREREQ_PM         => {},
    ($] >= 5.005 ?     ## Add these new keywords supported since 5.005
      (ABSTRACT_FROM  => 'lib/CLR.pm', # retrieve abstract from module
       AUTHOR         => 'A. U. Thor <a.u.thor@a.galaxy.far.far.away>') : ()),
    LIBS              => ['"-LC:\Program Files\Microsoft Visual Studio 8\VC\PlatformSDK\Lib"'],
    DEFINE            => '',
    INC       => '-I. "-IC:\Program Files\Microsoft Visual Studio 8\VC\PlatformSDK\Include"',
    CC => 'cl /clr /TP',
    LDDLFLAGS => '-dll -nologo -nodefaultlib -debug -opt:ref,icf -libpath:"C:\Perl\lib\CORE"
    -machine:x86 "C:\Program Files\Microsoft Visual Studio 8\VC\PlatformSDK\Lib\mscoree.lib"
    "C:\Program Files\Microsoft Visual Studio 8\VC\lib\msvcmrt.lib"'
);

Visual C++ 2005ではマニフェストの使用が必須なので,Perl実行ファイルも影響を受ける。そこで,以下のようなperl.exe.manifestを作成してperl.exeと同じディレクトリに置いた。

<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type='win32' name='Microsoft.VC80.CRT' version='8.0.50608.0'
      processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b' />
    </dependentAssembly>
  </dependency>
</assembly>

これでビルドの準備が出来たので,以下のように入力してビルドする。

perl Makefile.PL
vcvars32
nmake

ビルドに成功したら,clr.plというテストコードを作成して結果を見る。

use ExtUtils::testlib;
use CLR;

CLR::hello();

スクリーンショット

f:id:bosh:20060722040400:image

f:id:bosh:20060722041050:image