为什么必须从共享库调用hs_init(不是静态链接)

Ed *_*ehn 7 haskell ffi

我写了一个简单的haskell模块,我可以将其转换为共享库:

{-# LANGUAGE ForeignFunctionInterface #-}

module Safe where

import Foreign.C.Types

add :: Int -> Int -> Int
add p q = p + q

hs_add :: CInt -> CInt -> CInt
hs_add a b = fromIntegral (add (fromIntegral a) (fromIntegral b))

foreign export ccall hs_add :: CInt -> CInt -> CInt
Run Code Online (Sandbox Code Playgroud)

用命令

ghc -O2 -dynamic -shared -fPIC -o libAdd.so Add.hs -lHSrts-ghc8.2.2
Run Code Online (Sandbox Code Playgroud)

以下程序工作正常:

#include <stdio.h>
#include <dlfcn.h>
#include <HsFFI.h>

#define _LIB_INIT

int main(int argc, char *argv[])
{
    void* handle;

    static char *argv_N[] = { NULL }, **argv_ = argv_N;
    static int argc_ = 0;

    handle = dlopen("./libAdd.so", RTLD_NOW);
    if (!handle)
    {
        fprintf(stderr, "%s\n", dlerror());
        return 12;
    }
    else
        fprintf(stderr, "Successfully loaded library\n");

#ifdef _LIB_INIT
    void (*hs_init_l)(int *argc, char **argv[]) = dlsym(handle, "hs_init");
    hs_init_l(&argc_, &argv_);
#else
    hs_init(&argc_, &argv_);
#endif

    int (*hs_add)(int a, int b) = dlsym(handle, "hs_add");
    if (!hs_add)
    {
        fprintf(stderr, "Unable to load func : %s\n", dlerror());
        return 3;
    }
    else
        fprintf(stderr, "Successfully loaded function\n");

    int a=8, b=12;
    printf("%d + %d = %d\n", a, b, hs_add(a, b));

    dlclose(handle);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当我用它编译它

ghc --make -no-hs-main -optc-O test.c -o test
Run Code Online (Sandbox Code Playgroud)

但是,如果我删除了行定义_LIB_INIT,我得到

Successfully loaded library
Successfully loaded function
newBoundTask: RTS is not initialised; call hs_init() first
Run Code Online (Sandbox Code Playgroud)

换句话说,如果我hs_init从共享库调用它可以工作,但如果我将其称为静态链接副本,则该hs_add函数无法识别它.

这些有什么区别?