1.はじめに
P/Invoke(Platform Invoke、プラットフォーム呼び出し)は.NET Frameworkで提供されている、マネージコードからプラットフォームに依存したネイティブライブラリ内のアンマネージ関数を呼び出す機能です。
Windows上の.NET Framework環境では、マネージコードからダイナミックリンクライブラリ(*.dll)内の関数を呼び出す際に使われますが、Linux上のMono環境では、シェアードライブラリ(*.so)内の関数を呼び出す際に使用することができます。
本稿では、Mono環境での基本的なP/Invokeの使用方法、また、P/Invokeを使用した、OpenCOBOLで作成したシェアードライブラリ内の関数を呼び出す方法について解説を行います。
Monoはマルチプラットフォーム向け.NET Framework互換環境です。Monoについては、以下の記事を参考にしてください。
OpenCOBOLについては、布施 榮一氏による以下の記事を参考にしてください。
2.対象読者
- Monoを試してみたい人
- .NET初学者
3.必要な環境
以下の環境で動作確認を行いました。
- OS:openSUSE 10.3(LANG=ja_JP.UTF8)
- Mono 1.9.1
- GCC 4.2.1
- OpenCOBOL 1.0
- mlterm 2.9.3
4.P/Invokeを使用してみた
Cライブラリ内関数の呼び出し例
少し古いですが『.NETアプリをLinux対応にするMono』(developerWorks)においてP/Invokeを使用した数学ライブラリ(libm)内の平方根関数(sqrt)を呼び出すサンプルコードが掲載されています。それを参考にした以下のコードを試してみると
using System;
// P/Invokeサービス提供元
using System.Runtime.InteropServices;
namespace PInvokeExample
{
  public class Example1
  {
    //DllImportAttribute属性による数学ライブラリ(libm.so)の指定
    [DllImport("libm")]
    // 呼び出す関数のプロトタイプ宣言
    static extern double sqrt(double element);
    public static void Main(string[] args)
    {
      double e;
      if (args.Length == 1 && Double.TryParse(args[0], out e))
      {
        Console.WriteLine("「{0}」の平方根は「{1}」。", e, sqrt(e));
      }
      else
      {
        Console.WriteLine("Usage: PInvokeExample1.exe [数値]");
      }
    }
  }
}
/*
 * ビルド:
 *
 *   gmcs PInvokeExample1.cs
 *
 * 実行:
 *
 *   mono PInvokeExample1.exe [数値]
 *
 */
> mono PInvokeExample1.exe 4649 「4649」の平方根は「68.1835757349231」。
という感じになります。
DllImportAttribute属性で使用するCライブラリを指定し、使用する関数のプロトタイブ宣言(static、extern修飾子を付与する)を行うことで、Cライブラリ内の関数を呼び出すことが可能になります。
プロトタイプ宣言時のメソッド(関数)の引数の型については、呼び出し元(マネージ)と呼び出し先(アンマネージ)の対応をとる必要があります。『プラットフォーム呼び出しのデータ型』(msdn)を参考にしてください。

 
              
               
                          
                           
                          
                           
                          
                           
                          
                           
                          
                           
                          
                           
                          
                           
                          
                           
                          
                           
                          
                           
                          
                           
                              
                               
                              
                               
                              
                               
                              
                               
                              
                               
                      
                     
                      
                     
                      
                     
                      
                     
                      
                     
                      
                     
                      
                     
															
														 
															
														.png) 
     
     
     
     
     
													 
													 
													 
													 
													 
										
									
 
                    