Haskellを使ってアプリケーションを作成しようとすると,ライブラリの機能不足に遭遇することがあります。不足しているこうした機能の中には,C言語で書かれたライブラリやOSのAPIなどの力を借りなければ記述できないものがあります。 このためHaskellでは,第7回で触れたように,実行環境の外にある他言語のライブラリを扱うためにFFIという機能を用意しています。FFIを使えば,Haskellにはない機能を実装できます。 今回はFFIの基本的な使い方を説明します。 FFI使用の最初の一歩 最初に,FFIを使ったごく簡単な関数呼び出しを見てみましょう。以下のようなコードで,HaskellからCの関数を呼び出すことができます。 {-# LANGUAGE ForeignFunctionInterface #-} module SimpleFFIExample where foreign impor
Haskellのなんでもアリ具合。 ライブラリをビルドしてるとちょいちょい見えるFFIという文字列、気になって調べてみると、ForeignFunctionInterfaceというものがあって、これはHaskellからCの関数を呼び出すためのモジュールというか拡張らしい。 Haskellのものすごいライブラリの充実度の影にはこういうものがあったりするんですね。 ということでちょっと遊んでみました。 だいたいこの記事のトレスです。 本物のプログラマはHaskellを使う - 第22回 FFIを使って他の言語の関数を呼び出す:ITpro 既存のライブラリを呼ぶ 上の記事に習って、libmのsinを呼び出してみます。 まず、何はなくともmanです。sin(3)のmanを見ると、 NAME sin, sinf, sinl - sine function SYNOPSIS #include doubl
Haskellの代数的データ型とCの構造体を通信するためにhsc2hsというツールを使うと便利らしい。次のHogeという構造体でテストしてみた。 サンプルコード // Types.h struct Hoge { uint32_t field; }; -- Types.hsc {-# LANGUAGE ForeignFunctionInterface #-} #include "Types.h" data Hoge = Hoge { field :: UINT } deriving (Show,Eq) instance Storable Hoge where sizeOf = #size struct Hoge alignment = sizeOf peek (Hoge x) = (#peek struct Hoge, field) x poke ptr (Hoge x) = (#poke
The error was detected while processing this request. Be sure of followings: The CGI script does exist. The permission of CGI script is 755. The Perl path in CGI script is #!/usr/local/bin/perl. CGIスクリプトの呼び出し中にエラーが発生しました。 下記の点をご確認ください。 ・CGIスクリプトが存在すること。 ・CGIスクリプトのパーミッションが755であること。 ・CGIスクリプトのperlのパスが #!/usr/local/bin/perl であること。
C言語は、言語の都合上、関数へ渡したアドレスを用いて戻り値を受け取ることがしばしばあります。 extern "C" void ReceivePointer( int* p ) { *p = 100; }これをHaskellで受け取るために、次のような手順をとります。 allocaでスタック上にメモリを割り当てる Cの関数へポインタを渡して値を受け取る ポインタ先の値をpeek関数で取得 (alloca関数が終わるのでメモリが開放される) 型が理解しやすくなるように関数を分割して記述するとこんな感じ。 {-# LANGUAGE ForeignFunctionInterface #-} import Foreign.Storable import Foreign.Marshal import Foreign.Ptr foreign import ccall "ReceivePointer" c
この記事はHaskell Advent Calendarのために書いたものです。 FFIでCの関数を呼び出すところまではすんなりいったので、次C++行ってみよう!として ドハマりしたという内容です。 C++でクラスを作成して、ラッパー関数を書き、Haskellから呼び出すという手順でやってみます。 とりあえず何も考えずに以下のコードを書きました。 point.h point.cpp wrapper.cpp main.hs /* point.h */ class Point{ public: Point(int, int); int getX(); int getY(); private: int x, y; }; /* point.cpp */ #include "point.h" Point::Point(int x, int y){ this->x = x; this->y = y;
FFIでC言語を呼び出せたので、extern "C"でラップした.NET APIを呼び出せるか試しました。Windows FormsでGUIが表示できました。右がスクリーンショットで、以下がソースです。 https://gist.github.com/738961 gccではC++/CLIを扱えないため、DLLはVisual C++ 2010 Express Editionで作成しました。今回はテスト目的のためラッパーを自作しましたが、hs-dotnetという汎用ラッパーが存在します。 id:sirocco:20101026:1288085914 今回は使いませんが、HaskellとF#を連携させることもできそうです。 マーシャリング マネージオブジェクトはpinで止めないとポインタが取り出せません。面倒なのでオブジェクトを配列に入れて、インデックスをハンドルとして扱うことにしました。この
はてなグループの終了日を2020年1月31日(金)に決定しました 以下のエントリの通り、今年末を目処にはてなグループを終了予定である旨をお知らせしておりました。 2019年末を目処に、はてなグループの提供を終了する予定です - はてなグループ日記 このたび、正式に終了日を決定いたしましたので、以下の通りご確認ください。 終了日: 2020年1月31日(金) エクスポート希望申請期限:2020年1月31日(金) 終了日以降は、はてなグループの閲覧および投稿は行えません。日記のエクスポートが必要な方は以下の記事にしたがって手続きをしてください。 はてなグループに投稿された日記データのエクスポートについて - はてなグループ日記 ご利用のみなさまにはご迷惑をおかけいたしますが、どうぞよろしくお願いいたします。 2020-06-25 追記 はてなグループ日記のエクスポートデータは2020年2月28
hsc2hsコマンドを使うと、CコードのHaskellバインディングを書く作業を一部自動化することができる。このコマンドは、特別な構文要素の埋め込まれたHaskellのコードを読み、Cのヘッダから得た情報を使ってこれらの要素を処理し、本当のHaskellファイルを出力する。この特別な構文要素は、HaskellからCのデータにアクセスするにあたって必要なことを扱う。 hsc2hsはCファイルとCヘッダを出力することもある。Cファイルには、プログラムにリンクすべき追加のC関数が置かれ、ヘッダファイルは、そのHaskellモジュールがコンパイルされてできるCコードからincludeされるものである。この二つのファイルは#defという構文要素(下記参照)が使われたときに作られる。 hsc2hsは実際には直接Haskellコードを出力するわけではない。問題のヘッダをインクルードするCプログラムを作り
(今回は GUI というより FFI な気がする.でも目的は GUI だからいいか.) 前回作成した GUI の FlipIt を改良した. 改良は以下の2点 周期を増加. 解を表示. 周期の増加 前回は マスの変化が 白→黒→白→黒→… だったが,今回はこの周期を変更できるようにした. 白→灰→黒→白→灰→黒→… 内部的には Bool の2次元配列を Int の2次元配列に変更しただけ. 描画の色を少し調整した程度. ただ,解を求める際にガウスの消去法を使用するので,周期は素数でないと問題が生じる. また,周期が大きすぎても,わけわかめになるだけなので,最大周期は7に設定している. 解を表示 ガウスの消去法をやるだけといえば,それだけ. ただ,以前にC++で書いたことがある. そこで,今回は Haskell の FFI(Foreign Function Interface) を使って外部
Real World Haskellの読書メモが停滞していますが、読む方は地道に進んでいます。 今17章のFFIのところ。 FFIとは、Foreign Function Interfaceの略で、Haskellプログラムの中で他の言語の関数を読んだり、その逆をしたりといった話。 本の中では、HaskellからCの関数を呼ぶ話がメインです。 一読しかしてなくて、まだわかっていないところも多くあるのだけれど、例えばCで書いたHello WorldをHaskellから呼び出すのはとっても簡単です。 用意するファイルは3つ。 hello.h #ifndef HELLO_H #define HELLO_H #include <stdio.h> void hello(void); #endif /* HELLO_H */ hello.c #include "hello.h" void hello(vo
リリース、障害情報などのサービスのお知らせ
最新の人気エントリーの配信
処理を実行中です
j次のブックマーク
k前のブックマーク
lあとで読む
eコメント一覧を開く
oページを開く