gpt4 book ai didi

haskell - Haskell 与 c 的接口(interface)

转载 作者:行者123 更新时间:2023-12-03 06:37:04 24 4
gpt4 key购买 nike

我一直在想用 haskell 创建 midori 插件会很好,但这似乎几乎是不可能的。问题在于通过 ffi 导出 haskell 函数,因为 ghc 编译器使用了大量的 -u 开关。

有人见过 haskell 在类似的上下文中使用,而不必用 ghc 替换 gcc 吗?如果是这样,结果如何?他们经历了哪些困难?

编辑:需要一些示例,因此这里:

导出.hs

{-# LANGUAGE ForeignFunctionInterface #-}
module Export where
import Foreign.C
import Foreign.C.Types

foo :: IO Int
foo = return 2

foreign export ccall foo :: IO Int

test.c(ifdefs 被剪断)

#include <stdio.h>
#include "HsFFI.h"
#include "export_stub.h"

extern void __stginit_Export(void);

int main(int argc, char **argv)
{
int i;
hs_init(&argc, &argv);
hs_add_root(__stginit_Export);
i = foo();
printf("%d\n", i);
hs_exit();
return 0;
}

使用 ghc --make -no-hs-main export.hs test.c 编译会创建一个 a.out可以运行的可执行文件。 ghc 使用以下命令进行链接:

collect2 --build-id --eh-frame-hdr -m elf_i386 --hash-style=both -dynamic-linker/lib/ld-linux.so.2 -o a.out -z relro -u ghczmprim_GHCziTypes_Izh_static_info -u ghczmprim_GHCziTypes_Czh_static_info -u ghczmprim_GHCziTypes_Fzh_static_info -u ghczmprim_GHCziTypes_Dzh_static_info -u base_GHCziPtr_Ptr_static_info -u base_GHCziWord_Wzh_static_info -u base_ GHCziInt_I8zh_static_info -u base_GHCziInt_I16zh_static_info -u base_GHCziInt_I32zh_static_info -u base_GHCziInt_I64zh_static_info -u base_GHCziWord_W8zh_static_info -u base_GHCziWord_W16zh_static_info -u base_GHCziWord_W32zh_static_info -u base_GHC ziWord_W64zh_static_info -u base_GHCziStable_StablePtr_static_info -u ghczmprim_GHCziTypes_Izh_con_info - u ghczmprim_GHCziTypes_Czh_con_info -u ghczmprim_GHCziTypes_Fzh_con_info -u ghczmprim_GHCziTypes_Dzh_con_info -u base_GHCziPtr_Ptr_con_info -u base_GHCziPtr_FunPtr_con_info -u base_GHCziStable_StablePtr_con_info -u ghczmprim _GHCziBool_False_closure -u ghczmprim_GHCziBool_True_closure -u base_GHCziPack_unpackCString_closure -u base_GHCziIOziException_stackOverflow_closure -u base_GHCziIOziException_heapOverflow_closure -u base_ControlziExceptionziBase_nonTermination_closure -u base_GHCziIOziException_blockedIndefinitelyOnMVar_closure -u base_GHCziIOzi Exception_blockedIndefinitelyOnSTM_closure -u base_ControlziExceptionziBase_nestedAtomically_closure -u base_GHCziWeak_runFinalizzerBatch_closure -u base_GHCziTopHandler_runIO_closure -u base_GHCziTopHandler_runNonIO_closure -u base_GHCziConc_ensureIOManagerIsRunning_closure -u base_GHCziConc_runSparks_closure -u base_GHCziConc_runHandlers_closure/usr/lib/gcc/i486-linux-gnu/4.4.3/../../../../lib/crt1.o/usr/lib/gcc/i486-linux-gnu/4.4.3/../../../../lib/crti.o/usr/lib/gcc/i486-linux-gnu/4.4.3/crtbegin.o -L/usr/lib/ghc-6.12.1/base-4.2.0.0 -L/usr/lib/ghc-6.12.1/integer-gmp-0.2.0.0 -L/usr/lib/ghc-6.12.1/ghc-prim-0.2.0.0 -L/usr/lib/ghc-6.12.1 -L/usr/lib/gcc/i486-linux-gnu/4.4.3 -L/usr/lib/gcc/i486-linux -gnu/4.4.3 -L/usr/lib/gcc/i486-linux-gnu/4.4.3/../../../../lib -L/lib/../lib -L/usr/lib/../lib -L/usr/lib/gcc/i486-linux-gnu/4.4.3/../../.. -L/usr/lib/i486-linux-gnu 导出.o export_stub.o test.o -lHSbase-4.2.0.0 -lHSinteger-gmp-0.2.0.0 -lgmp -lHSghc-prim-0.2.0.0 -lHSrts -lm -lffi -lrt -ldl -lgcc --as-needed -lgcc_s - -no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed/usr/lib/gcc/i486-linux-gnu/4.4.3/crtend.o/usr/lib/gcc/i486-linux-gnu/4.4.3/../../../../lib/crtn.o

删除 -u 开关(只留下 -l、-L 和一些额外的标志)前面的命令不会编译并返回(大约 50 个左右)行)

/usr/lib/ghc-6.12.1/libHSrts.a(RtsAPI.o): In function `rts_mkFunPtr':
(.text+0x5a9): undefined reference to `base_GHCziPtr_FunPtr_con_info'
/usr/lib/ghc-6.12.1/libHSrts.a(RtsAPI.o): In function `rts_mkString':
(.text+0x60f): undefined reference to `base_GHCziPack_unpackCString_closure'

最佳答案

我能够解决这个问题。

我正在使用以下文件:

main.c

#include <stdio.h>
#include "lib_stub.h"
int main(int argc, char **argv)
{
puts("foo");
printf("%d\n", hsfun(5));
return 0;
}

lib.hs

{-# LANGUAGE ForeignFunctionInterface #-}
module Test where
import Foreign.C.Types

hsfun :: CInt -> IO CInt
hsfun x = do
putStrLn "Hello from haskell"
return (42 * x)

foreign export ccall hsfun :: CInt -> IO CInt

module_init.c

#include <HsFFI.h>
extern void __stginit_Test(void);

static void library_init(void) __attribute__((constructor));
static void library_init(void)
{
static char *argv[] = { "libtest.so", 0 }, **argv_ = argv;
static int argc = 1;

hs_init(&argc, &argv_);
hs_add_root(__stginit_Test);
}

static void library_exit(void) __attribute__((destructor));
static void library_exit(void)
{
hs_exit();
}

我正在使用 ghc --make -shared -dynamic -fPIC -o
libtest.so lib.hs module_init.c -lHSrts-ghc6.12.1
-optl-Wl,-rpath,/usr/lib/ghc-6.12.1/ -L/usr/lib/ghc-6.12.1
编译库和可执行文件 gcc -c main.c -I/usr/lib/ghc-6.12.1/include -L. -ltest
-Wl,-rpath=$PWD

重要的部分是使库共享并拥有 rts 库链接也不是默认的。 rpath 使得它可以在没有 LD_LIBRARY_PATH 的情况下运行。

http://weblog.haskell.cz/pivnik/building-a-shared-library-in-haskell/

http://www.well-typed.com/blog/30

关于haskell - Haskell 与 c 的接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4418901/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com