diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/Lib.hs | 6 | ||||
| -rw-r--r-- | src/Main.hs | 14 | ||||
| -rw-r--r-- | src/harness/main.c | 65 | ||||
| -rw-r--r-- | src/harness_adapter.c | 12 |
4 files changed, 97 insertions, 0 deletions
diff --git a/src/Lib.hs b/src/Lib.hs new file mode 100644 index 0000000..d36ff27 --- /dev/null +++ b/src/Lib.hs @@ -0,0 +1,6 @@ +module Lib + ( someFunc + ) where + +someFunc :: IO () +someFunc = putStrLn "someFunc" diff --git a/src/Main.hs b/src/Main.hs new file mode 100644 index 0000000..c43ef13 --- /dev/null +++ b/src/Main.hs @@ -0,0 +1,14 @@ +module Main (main) where +import Control.Monad.Writer (execWriter, MonadWriter (tell)) + +foreign export ccall call_in :: IO () +call_in :: IO () +call_in = putStrLn $ execWriter $ do + tell "Yo," + tell " This was " + tell "Called" + tell " From" + tell " C!!" + +main :: IO () +main = putStrLn "This should be dynamically linked!\n" diff --git a/src/harness/main.c b/src/harness/main.c new file mode 100644 index 0000000..6666e5e --- /dev/null +++ b/src/harness/main.c @@ -0,0 +1,65 @@ +#include <stdio.h> + +#include <dlfcn.h> + +typedef void* dllib_t; + +dllib_t open_library(const char* library, int* err) +{ + dllib_t lib = dlopen(library, RTLD_LAZY); + + if (!lib) { + fprintf(stderr, "Error opening shared library: %s\n", dlerror()); + *err = 1; + } + *err = 0; + return lib; +} + +void* getsym(dllib_t handle, char* sym, int* err) +{ + void* ret = dlsym(handle, sym); + if (!ret) { + fprintf(stderr, "Unable to read symbol '%s'\n", sym); + *err |= 1; + return NULL; + } + return ret; +} + +void use_library(int argc, char** argv, dllib_t lib, int* err) +{ + *err = 0; + + void (*init)(int* argc, char*** argv) = getsym(lib, "plugin_init", err); + void (*teardown)() = getsym(lib, "plugin_teardown", err); + void (*sym)() = getsym(lib, "call_in", err); + + if (!sym) { + *err = 1; + fprintf(stderr, "Unable to find symbol call_in.\n"); + return; + } + + init(&argc, &argv); + sym(); + teardown(); +} + +int main(int argc, char** argv) +{ + if (!argv[0] && !argv[1]) { + fprintf(stderr, "Missing argument.\n"); + return 1; + } + + int err = 0; + dllib_t lib = open_library(argv[1], &err); + + if (err) { + return err; + } + + use_library(argc, argv, lib, &err); + return 0; +} diff --git a/src/harness_adapter.c b/src/harness_adapter.c new file mode 100644 index 0000000..9cd8118 --- /dev/null +++ b/src/harness_adapter.c @@ -0,0 +1,12 @@ +#include <stdio.h> +#include "HsFFI.h" + +void plugin_init(int* argc, char*** argv) +{ + hs_init(argc, argv); +} + +void plugin_teardown() +{ + hs_exit(); +} |