与用C ++编写的静态库链接的Haskell可执行文件得到了“未定义的引用”

时间:2011-10-17 11:11:02

标签: haskell ffi cross-language

我创建了一个静态库:

// 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。我真的很困惑。


终于在维基上获得了一些东西: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上失败。

0 个答案:

没有答案