我创建了一个静态库:
// foo.h
extern "C" {
int foo (const char* arg0, int arg1);
}
// foo.cpp
#include "foo.h"
// implementation of foo
这段代码被编译foo.o
并打包到libfoo.a
安装到 MinGW 的lib
目录中(我在 Windows 上,使用 GCC 工具链)。
我想要做的是将此函数包装在 Haksell 代码中,因此典型的 FFI 绑定如下:
-- Foo.hs
{-# LANGUAGE ForeignFunctionInterface #-}
module Foo where
foreign import ccall "foo"
c_foo :: CString -> CInt -> IO (CInt)
extra-libraries
也被添加到.cabal
文件中:
...
extra-libraries: foo, stdc++
但是 GHC 对未定义的引用表示不满foo
:
.dist-scion\build\path\to\Foo.o:fake:(.text+0x514): undefined reference to `foo'
在nm
库中找出库中foo
实际存在的功能(名称上有一些装饰)后,我被困在这里......
[编辑]
我还尝试使用 cabal 构建 haskell 包:
cabal configure
cabal build
结果显示:
Loading object (dynamic) foo ... ghc.exe: foo: ....
<command line>: user specified .o/.so/.DLL could not be loaded (addDLL: could not load DLL)
那么这应该与静态/动态链接有关吗?因为我注意到 GHC 想要加载.o/.so/.DLL
但不是.a
。我真的很困惑。
终于在wiki上得到了一些东西:Cxx Foreign Function Interface
[编辑]
一种解决方案是-optl-lfoo -optl-lstdc++
在.cabal
文件中使用,而不是extra-libraries
. 并且可以通过将声明包装在以下中来轻松解决命名问题extern "C"
:
#ifdef __cplusplus
extern "C" {
#endif
extern int foo (const char*, int);
#ifdef __cplusplus
}
#endif
这在 EclipseFP 中有效,因为它使用 Scion。但它仍然失败cabal build
。