summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md1
-rw-r--r--ffi/Foo.hs10
-rw-r--r--ffi/Makefile9
-rw-r--r--ffi/foomain.c21
4 files changed, 41 insertions, 0 deletions
diff --git a/README.md b/README.md
index ece51c4..e0c742c 100644
--- a/README.md
+++ b/README.md
@@ -4,6 +4,7 @@ This repo holds a collection of some of my Haskell sources:
* [./base64/](https://gitweb.softwarefools.com/?p=miguel/haskell.git;a=tree;f=base64) - encoder / decoder
* [./calcGTK/](https://gitweb.softwarefools.com/?p=miguel/haskell.git;a=tree;f=calcGTK) - Parsing with Parsec and GUI with GTK
+* [./ffi/](https://gitweb.softwarefools.com/?p=miguel/haskell.git;a=tree;f=ffi) - sample use of the foreign function interface (ffi)
* [./freedomain/](https://gitweb.softwarefools.com/?p=miguel/haskell.git;a=tree;f=freedomain) - simple multithreaded domain checker based on DNS lookup
* [./hulls/](https://gitweb.softwarefools.com/?p=miguel/haskell.git;a=tree;f=hulls) - find convex and concave hulls for a set of points
* [./mnist/](https://gitweb.softwarefools.com/?p=miguel/haskell.git;a=tree;f=mnist) - hello world of neuronal networks
diff --git a/ffi/Foo.hs b/ffi/Foo.hs
new file mode 100644
index 0000000..286a8bf
--- /dev/null
+++ b/ffi/Foo.hs
@@ -0,0 +1,10 @@
+module Foo where
+
+foreign export ccall foo :: Int -> IO Int
+
+foo :: Int -> IO Int
+foo n = return (length (f n))
+
+f :: Int -> [Int]
+f 0 = []
+f n = n:(f (n-1))
diff --git a/ffi/Makefile b/ffi/Makefile
new file mode 100644
index 0000000..6f098a6
--- /dev/null
+++ b/ffi/Makefile
@@ -0,0 +1,9 @@
+hask_from_c: Foo.hs foomain.c
+ stack ghc -- Foo.hs
+ stack ghc -- -no-hs-main Foo.o foomain.c -o hask_from_c
+
+clean:
+ - rm *.o
+ - rm *.hi
+ - rm Foo_stub.h
+ - rm hask_from_c
diff --git a/ffi/foomain.c b/ffi/foomain.c
new file mode 100644
index 0000000..70d891c
--- /dev/null
+++ b/ffi/foomain.c
@@ -0,0 +1,21 @@
+#include <stdio.h>
+#include "HsFFI.h"
+
+#ifdef __GLASGOW_HASKELL__
+#include "Foo_stub.h"
+#endif
+
+int main(int argc, char *argv[])
+{
+ int i;
+
+ hs_init(&argc, &argv);
+
+ for (i = 0; i < 5; i++) {
+ printf("%d\n", foo(2500+i));
+ printf("%d\n", foo(2500+i));
+ }
+
+ hs_exit();
+ return 0;
+}