Bagikan ke: Twitter | Facebook | LinkedIn
Daftar isi
Pendahuluan
kita terkadang memerlukan sebuah library / fungsi yang akan membantu kita membuat sebuah aplikasi, namun ketika melihat dokumentasi ternyata bahasa program yang sedang kita dipakai tidak mengimplementasikanya, disinilah kita bisa menggunakan FFI untuk memanggil fungsi yang kita inginkan dari bahasa lain.
Apa itu FFI
Foreign function interface atau disingkat FFI adalah sebuah mekanisme yang memungkinkan kita untuk menjalankan program dari bahasa lain, FFI sangatlah berguna karna kita dapat mengimplementasikan sebuah fungsi yang tidak dapat dilakukan di bhs program yang saat ini kita pakai contohnya adalah memanggil fungsi dari library cURL atau SDL.
Tujuan Menggunakan FFI
salah satu tujuanya adalah bahasa program yang kita pakai kadang tidak memiliki suatu fungsi yang sesuai maka kita bisa menggunakan / memanggilnya ke dalam program melalui FFI atau kita bisa dengan mudah melakukan atau mengimplementasikan suatu algoritma dalam bahasa lain.
tapi perlu diperhatikan beberapa FFI memiliki kekuranganya sendiri, contohnya di bahasa program Java kita bisa menggunakan FFI dengan menggunakan JNI (Java Native Interface), program yang dibuat dengan JNI tidak akan mendapat kelebihan dari bahasa yang berjalan di JVM, contoh lainya bahasa Rust, karna Rust merupakan bahasa yang sangat mementingkan keamanan memori jika kita memanggil FFI dari bahasa C maka kita tidak akan mendapatkan kelebihanya.
Contoh penggunaan FFI
Biasanya FFI akan memanggil menggunakan bahasa C, meskipun kita bisa menggunakan C++ atau bahasa lain, biasanya FFI hanya akan menerima kode assembly dengan notasi dari bahasa C
Haskell
saya akan membuatakan sebuah contoh pemanggilan fungsi dari bahasa c ke
bahasa haskell, pertama-tama saya akan membuat dua buah file yang
bernama Main.hs
dan Cbits.c
.
seperti inilah isi dari file Cbits.c
#include <stdio.h>
#include <stdlib.h>
void print_something(){
("testing FFI on Haskell\n");
printf}
int* testing_mem()
{
int *p = (int*) malloc(sizeof(int));
*p = 10;
("the number is %d \n", *p);
printfreturn p;
}
int cmain()
{
int x;
("please input some number : ");
printf("%d", &x);
scanf("the input number is %d \n", x);
printfreturn 0;
}
dan file Main.hs
akan berisi
{-# LANGUAGE ForeignFunctionInterface #-}
import Foreign.Ptr ( Ptr )
import Foreign.Storable ( Storable(peek) )
import Foreign.Marshal.Alloc ( free )
import Foreign.C.Types ( CInt(..) )
import ccall "print_something" c_print_something :: IO ()
foreign import ccall "testing_mem" c_testing_mem :: IO (Ptr CInt)
foreign import ccall "cmain" c_main :: IO CInt
foreign
test :: IO CInt
= do c_main
test
main :: IO ()
= do
main <- c_print_something
_ <- c_testing_mem
ptr <- peek ptr
x
free ptr
c_mainputStr ""
untuk mengkompilasinya kita bisa menggunakan perintah GHC seperti ini :
ghc -o main Main.hs Cbits.c
opsi -o
disini agar hasil kompilasinya bernama main
dalam beberapa kasus kita mungkin memanggil sebuah library yang dipakai
di bahasa C, kita bisa melakukanya dengan opsi -l<nama library>
contohnya jika saya ingin menggunakan library cURL saya saya hanya perlu
menjalankan perintah :
ghc -o main Main.hs Cbits.c -lcurl
bisa dilihat dalam program C saya membuat 3 buah fungsi, fungsi untuk mencetak sebuah string ke layar, fungsi yang didalamnya terdapat pointer yang berisi address memori yang teralokasikan dan juga fungsi yang mengambil sebuah input lalu mencetaknya, semua yang saya panggil bisa berjalan dengan lancar di dalam bahasa Haskell, dari sini kita bisa membuat sebuah program yang lebih fleksibel karna memiliki kelebihan dari kedua bahasa yang berbeda.
selain menggunakan fungsi yang kita buat kita juga mampu memanggil
fungsi yang berasal dari header system, contohnya saya bisa menggunakan
printf dalam haskell dengan mengimport stdio.h
seperti ini :
{-# LANGUAGE CApiFFI #-}
import Foreign.C.String ( CString, withCString )
import capi "stdio.h printf" c_printf :: CString -> IO ()
foreign
printf :: String -> IO ()
= withCString x c_printf
printf x
main :: IO ()
= printf "Hello world \n" main
Racket
dalam racket kita juga bisa langsung memanggil librari yang kita mau,
sebagai contoh kita bisa memanggil libc
lalu kita bisa jalankan
langsung di racketnya, contohnya seperti ini :
#lang racket
(require ffi/unsafe)
define libc
("libc.so.6"))
(ffi-lib
define printf
("printf" libc
(get-ffi-obj
(_fun _string -> _void)))
"Hello Worlds\n") (printf
kita juga bisa memanggil dari c program yang kita buat, tetapi kita harus membuat shared object terlebih dahulu, untuk membuat shared library kita bisa menggunakan perintah gcc :
gcc -shared -fpic -o <nama-output>.so <nama-source>.c
cara memanggilnya sama dengan sebelumnya
Daftar Pustaka
Haskell Wiki
→ Foreign Function InterfaceWikipedia
→ Foreign function interfaceRacket Docs
→ The Racket Foreign InterfaceFire Salamander Photo
→ by William Warby