我想用FFI调用C单头库。
这是Nuk.hs
{-# LANGUAGE CPP, ForeignFunctionInterface #-}
module Main where
import Foreign
import Foreign.C.Types
foreign import ccall unsafe "nuklear.h nk_sin"
c_nk_sin:: IO CFloat
main = print $ c_nk_sin (5)
在同一目录中,我有
nuklear.h
当我执行
stack ghc Nuk.hs
时,我得到[1 of 1] Compiling Main ( Nuk.hs, Nuk.o )
Linking Nuk ...
Nuk.o:r1Rq_info: error: undefined reference to 'nk_sin'
collect2: error: ld returned 1 exit status
`gcc' failed in phase `Linker'. (Exit code: 1)
我该如何解决?
最佳答案
如果它是仅标头的库,则需要C编译器为其生成目标文件,以便Haskell程序可以链接到定义。根据Nuklear的文档,您可以创建一个存根C文件:
// nuklear.c
#define NK_IMPLEMENTATION
#include "nuklear.h"
作为构建的一部分,将其编译(例如,使用
gcc -c nuklear.c -o nuklear.o
)以生成目标文件nuklear.o
,使用ar
(例如ar -csr libnuklear.a nuklear.o
)创建一个静态库libnuklear.a
,然后假设此归档文件位于libs
中,您将添加:extra-lib-dirs: libs
extra-libraries: nuklear
转到Cabal文件中的
executable
部分。 (或hpack的package.yml
中的相应部分。)为了对此进行协调,您可能需要一个Makefile来构建该库,并调用
stack
/ cabal
/ ghc
生成最终的构建结果。 This tutorial更详细地介绍了该过程。但是对于这个简单的用例,您也许可以在Cabal内部使用 c-sources
section来做到这一点:c-sources: nuklear.c
您可能还需要指定
includes
和include-dirs
,例如:includes: nuklear.h
关于haskell - Haskell FFI本地C header ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53146472/