外部ライブラリコール

Curlは外部ライブラリにアクセスすることができます。これによりC言語等で作成されたライブラリをコールし、結果を取得することができます。以下にサンプルをもとにして説明していきます。(ちなみにこのサンプルはWindowsのみで動きます。UNIX用のライブラリであれば、UNIX上でも実行することができます。)

当サンプルは、user32.dllに格納されているMessageBox 関数へのインターフェースを使用します。MessageBox は、単にメッセージ ボックスを表示します。インターフェースは以下のようになっています。

int MessageBox(
  HWND hWnd;
  LPCTSTR lpText;
  LPCTSTR lpCaption;
  UINT uType;
):int

パラメータには以下のような意味があります。
hWnd
メッセージボックスの上位ウィンドウへのハンドル。NULL の場合、このウィンドウにオーナーはありません。

lpText
表示されるテキスト。

lpCaption
ダイアログ ボックスのタイトルに表示されるテキスト。NULL の場合、既定のタイトルとしてエラーが使用されます。

uType
指定されたフラグに応じて、ダイアログ ボックスの内容と動作を変更します。フラグの種類は多数ありますが、この例で紹介しているのは、その一部です。

ライブラリをコールするクラスは、define-dll-classマクロを使って定義します。以下のようにサンプルでは、このコンストラクタ内で、SharedLibraryクラスを用いて対象DLL(user32.dll)をロードしています。construct-superでスーパークラスのコンストラクタを呼び出していますが、このスーパークラスはDLLInterfaceクラスです。 

{define-dll-class public WinMessageBox
  {defaults
    calling-convention = stdcall,
    string-rep = CStringUTF16
  }
 
  {constructor public {default}
    {construct-super {SharedLibrary “user32”}}
  } 

次にdll-methodで対象となる関数を定義することとなります。{defaults …} 句により、クラスに含まれた dll-method に直接、いくつかの既定値を設定できるようになります。これらの既定は、このクラスのサブクラスには適用されません。詳細はCurlのAPIリファレンスdefine-dll-classマクロを参照してください。

対象となる関数の定義については、同様の関数名をdll-methodのメソッド名としてセットするか、任意の名前を振り、括弧()で関数名を記載します。このサンプルでは後者の方法で定義しており、関数名はMessageBoxA、Curl内でのメソッドへのアクセスはshow-ascii-messageとなります。

{dll-method public {show-ascii-message (“MessageBoxA”)
                       hwin:CPointer = null,
                       text:StringInterface (rep = CString),
                       title:#StringInterface = null (rep = CString),
                       button-code:int = WinMessageBox.button-ok
                     }:int
}

…. 省略 ….

let box:WinMessageBox = {WinMessageBox}
let result:int =
    {box.show-message
        “Would you like a cookie?”,
         button-code =
             {bit-or
                 WinMessageBox.button-yes-no,
                 WinMessageBox.icon-question
             }
    }

実行結果 

 

 

コードサンプルのダウンロード

外部DLLコールのコードサンプル