Using Pascal Libraries with .NET and Mono/ja

From Free Pascal wiki
Jump to: navigation, search

English (en) | italiano (it) | 日本語 (ja)

日本語版メニュー
メインページ - Lazarus Documentation日本語版 - 翻訳ノート - 日本語障害情報


はじめに

Microsoft 社は、"アンマネージドコード(unmanaged code)" と非常に互換性のある.NET framework を提供しています。アンマネージドコードというと何か野蛮で危険なもののように聞こえますが、これはネイティブの Windows ライブラリの書式の"レガシー"なコードのことをいいます。Mono プロジェクトには Linux と MacOS X のネイティブライブラリに対して(.NET と)同様のサポートが含まれています。これは Free Pascal でコンパイルしたライブラリを Windows の .NET アプリケーションや Linux や Mac OS X の Mono のアプリケーションから使えることを意味します。

シンプルな Pascal ライブラリ

次のPascalコードをコピーして SimpleLib.pas というファイル名で保存して下さい:

library SimpleLib;

function MySucc(AVal : Int64) : Int64; stdcall;
begin
  Result := System.Succ(AVal);
end;

function MyPred(AVal : Int64) : Int64; stdcall;
begin
  Result := System.Pred(AVal);
end;

exports
{$IFDEF DARWIN}  {OS X entry points}
  MySucc name '_MySucc',
  MyPred name '_MyPred',
{$ENDIF}
  MySucc,
  MyPred;

end.

Mac OS X (DARWIN)上でコンパイルした場合、条件付きの指示に注意して下さい。どうも OS X ダイナミックリンカーは アンダースコアから始まるライブラリのエントリーポイントを探そうとするようです。

ここで Free Pascal でライブラリをコンパイルします:

 fpc -Sd SimpleLib.pas

Windows 上では、simplelib.dll というファイルを作成します。MacOS X 上では、libsimplelib.dylib というファイルを作成します。Linux 上では、simplelib.so というファイルを作成します。MacOS X や Linux では、コンパイルしたライブラリファイルを simplelib.dll にリネームします:

 mv libsimplelib.dylib simplelib.dll

シンプルな VB.NET アプリケーション

次の VB.NET コードを TestLib.vb というファイル名で保存して下さい:

Imports System
Imports System.Runtime.InteropServices

Public Class TestLib

  Const SimpLibName = "simplelib.dll"

   'Declare external functions using the DllImport attribute.
  <DllImport(SimpLibName, EntryPoint:="MySucc", _
             CallingConvention:=CallingConvention.StdCall)> _
             Public Shared Function Succ(ByVal AVal As Long) As Long
    End Function

  <DllImport(SimpLibName, EntryPoint:="MyPred", _
             CallingConvention:=CallingConvention.StdCall)> _
             Public Shared Function Pred(ByVal AVal As Long) As Long
    End Function

  Public Shared Sub Main()
  
    Dim TestVal As Long

    Try
      TestVal = 123
      Console.WriteLine("Value is " & TestVal)
      Console.WriteLine("Successor is " & Succ(TestVal))
      Console.WriteLine("Predecessor is " & Pred(TestVal))
    Catch e As Exception
      Console.WriteLine(e)
    End Try

  End Sub  'Main

End Class  'TestLib

もし Windows 上に .NET framework をインストールしているのなら、次のようにすればコードをコンパイルできます:

 [pathto]vbc TestLib.vb

[pathto] は .NET framework (.NET 1.1 での例: c:\windows\microsoft.net\framework\v1.1.4322\ ) へのパスです。これで TestLib.exe というファイルが作成されます。

もし Mono をインストールしてれば、同じように次の手順でコードをコンパイルすることができます:

 mbas TestLib.vb

今のところ、Mono の VB.NET コンパイラはアルファ版の段階で、このコードはコンパイルできないかもしれません。もしコンパイルエラーが出たら、C# バージョンでコンパイルしてみて下さい。

シンプルな C# アプリケーション

ここにはC#互換のコードがあります。これを TestLib.cs というファイル名で保存します。

using System;
using System.Runtime.InteropServices;

public class TestLib {
  
  const string SimpLibName = "simplelib.dll";

   //Declare external functions using the DllImport attribute.
  [DllImport(SimpLibName, EntryPoint="MySucc",
             CallingConvention=CallingConvention.StdCall)]
             public static extern long Succ(long AVal);

  [DllImport(SimpLibName, EntryPoint="MyPred", 
             CallingConvention=CallingConvention.StdCall)] 
             public static extern long Pred(long AVal);

  public static void Main()
  {
    long TestVal;

    try
    {
      TestVal = 123;
      Console.WriteLine("Value is " + TestVal);
      Console.WriteLine("Successor is " + Succ(TestVal));
      Console.WriteLine("Predecessor is " + Pred(TestVal));
    }
    catch(Exception e)
    {
      Console.WriteLine(e);
    }
  }
}

.NET を使って次の方法でコンパイルできます。

 [pathto]csc TestLib.cs

Mono を使って次の方法でコンパイルできます。


 mcs TestLib.cs

.NET、Monoのどちらであっても、TestLib.exe というファイルが作成されます。

シンプルなアプリケーションの実行

.NETでは、コンパイルしたアプリケーションを実行方法は次の通りです。

 testlib

.NET でライブラリを見つけられたら、アプリケーションはコンソール上に次の出力を行ないます:

 Value is 123
 Successor is 124
 Predecessor is 122

Mono であれば、次のように実行します:

 mono TestLib.exe

この際、Mono は simplelib.dll ファイルを探します --これが、上の Linux と Mac OS X 環境でライブラリ名を変更するように述べた理由です。

.NET/Mono の ".exe" ファイルは、実際にはネイティブコードを含んではいません。その代わり、.NET/Mono のランタイムによって実行されるバイトコードを含んでいます。その結果、Windows 上で作成した .NET の実行ファイルを、Mono を使ってリコンパイルすることなく Mac OS X や Linux 上で動かすことができるようになります(その逆も同様です)。

サポートを使用としてるプラットホーム用の Pascal ライブラリについてはリコンパイルする必要があります。

.Net/Mono からネイティブライブラリを使用する

なぜ、全てのコードを VB.NET や C# にしないのでしょうか?それは状況によって、それが最善ではない場合があるからです:

  • C# で書き直し(もしくは再デバッグ)したくないような巨大で完全な Pascal コードを持っている場合
  • ネイティブアプリケーション、.NET/Monoアプリケーションの両方から必要とされるネイティブライブラリを持っている場合
  • パフォーマンス上の理由がある場合(たいていの場合、 FPC や Delphi でコンパイルされたネイティブコードは .NET/Mono 上で動作する同じ内容のバイトコードに比べて速く動きます)
  • .NET/Mono では簡単にアタッチできないようなローレベルの処理システムが必要な場合
  • 多人数開発の .NET/Mono プロジェクトのために、習熟している言語による開発コードがすぐに必要な場合

Mono tips

1. Visual Basic は Linux や MacOS X からするとかなり異質ですので、C++(Object Pascal)によく似たC#で .NET や mono アプリケーションの開発をしたくなると思います。

2. Mac OS X の Mono はアンインストール用のスクリプトを含んでいます。新しいバージョンの Mono をインストールする際は、予めアンインストール用のスクリプトを実行してください:

  • ファインダーで /Library/Receipts を開きます
  • MonoFramework.pkg の上で Ctrl を押しながらマウスをクリックします。ポップアップメニュー上で必要なパッケージを選択します。
  • Contents フォルダをダブルクリックします。
  • Resources フォルダをダブルクリックします。
  • uninstallMono.sh をドラッグしてデスクトップにコピーします。
  • ターミナルを開きます。
  • cd desktop でデスクトップにカレントディレクトリを移します。
  • sudo ./uninstallMono.sh を実行します。パスワードを聞かれたら入力します。

3. 通常、あなたが作成したライブラリの中で Lazarus のユニットを使用しないでください。通常、ライブラリはユーザインタフェースを含んではいけません。System、SysUtils、StrUtils、DateUtils、Classes、Variants、Math のような Free Pascal のユニットに止めておいて下さい。

4. もし、作成するライブラリでどうしてもインターフェースが必要なら、Windows フォームアプリケーションとしてそれをプログラムして下さい。ここに簡単な例があります。これをコピーして MyForm.cs というファイル名で保存します。

using System.Windows.Forms;

public class MyForm: Form
{
  public static void Main()
  {
    MyForm aForm = new MyForm();

    aForm.Width = 350;

    Button b = new Button();
    b.Left = 15;
    b.Top = 20;
    b.Width = aForm.Width-30;
    b.Height = 30;
    b.Text = "A Button";
    aForm.Controls.Add(b);

    aForm.Text = "A .NET/Mono Windows Forms App";

    Application.Run(aForm);
  }
}

これを次のようにして、Mono でコンパイルします:

 mcs -r:System.Windows.Forms MyForm.cs

次のようにして実行します:

 mono MyForm.exe

Mac OS X 上では、Lazarus の実行がそうであるように、現バージョンの Mono も X11 を要求するので、 プログラムを実行するためには X11 ウィンドウ(ターミナルウィンドウではなく)を開いておく必要があります。

5. もし .NET や Mono から Pascal ライブラリを使用することに関して質問やコメントがあれば、Lazarus フォーラムにそれを投稿してください。