【问题标题】:Using a haskell function from C++: Undefined reference error使用 C++ 中的 haskell 函数:未定义的引用错误
【发布时间】:2011-12-28 17:09:42
【问题描述】:

我想用 C++ 调用 haskell 函数,并且确实使用了 http://www.haskell.org/ghc/docs/7.0.2/html/users_guide/ffi-ghc.html 上的教程

所以我有一个 haskell 文件 Foo.hs:

module Foo where

foreign export ccall foo :: Int -> IO Int

foo :: Int -> IO Int
foo n = return (length (f n))

f :: Int -> [Int]
f 0 = []
f n = n:(f (n-1))

被叫

ghc Foo.hs

其中创建了一个 Foo_stub.h:

#include "HsFFI.h"
#ifdef __cplusplus
extern "C" {
#endif
extern HsInt foo(HsInt a1);
#ifdef __cplusplus
}
#endif

一个Foo_stub.c:

#define IN_STG_CODE 0
#include "Rts.h"
#include "Stg.h"
#ifdef __cplusplus
extern "C" {
#endif

extern StgClosure Foo_zdffoozualy_closure;
HsInt foo(HsInt a1)
{
Capability *cap;
HaskellObj ret;
HsInt cret;
cap = rts_lock();
cap=rts_evalIO(cap,rts_apply(cap,(HaskellObj)runIO_closure,rts_apply(cap, Foo_zdffoozualy_closure,rts_mkInt(cap,a1))) ,&ret);
rts_checkSchedStatus("foo",cap);
cret=rts_getInt(ret);
rts_unlock(cap);
return cret;
}
static void stginit_export_Foo_zdffoozualy() __attribute__((constructor));
static void stginit_export_Foo_zdffoozualy()
{getStablePtr((StgPtr) &Foo_zdffoozualy_closure);}
#ifdef __cplusplus
}
#endif

它还创建了一个 Foo_stub.o 文件。

我现在创建了一个 main.cpp 文件:

#include "Foo_stub.h"
int main()
{
  foo(3);
}

并尝试编译它。

使用 g++ 失败:

$ g++ -I/usr/lib/ghc-7.0.3/include/ main.cpp Foo_stub.o
Foo_stub.o: In function `foo':
Foo_stub.c:(.text+0xa): undefined reference to `rts_lock'
Foo_stub.c:(.text+0x18): undefined reference to `rts_mkInt'
Foo_stub.c:(.text+0x20): undefined reference to `Foo_zdffoozualy_closure'
Foo_stub.c:(.text+0x28): undefined reference to `rts_apply'
Foo_stub.c:(.text+0x30): undefined reference to `base_GHCziTopHandler_runIO_closure'
Foo_stub.c:(.text+0x38): undefined reference to `rts_apply'
Foo_stub.c:(.text+0x48): undefined reference to `rts_evalIO'
Foo_stub.c:(.text+0x58): undefined reference to `rts_checkSchedStatus'
Foo_stub.c:(.text+0x62): undefined reference to `rts_getInt'
Foo_stub.c:(.text+0x6d): undefined reference to `rts_unlock'
Foo_stub.o: In function `stginit_export_Foo_zdffoozualy':
Foo_stub.c:(.text+0x80): undefined reference to `Foo_zdffoozualy_closure'
Foo_stub.c:(.text+0x85): undefined reference to `getStablePtr'
collect2: ld returned status 1

所以我尝试了 ghc --make。但这也失败了:

$ ghc --make main.cpp Foo_stub.o
cc1plus: Warning: Option »-Wimplicit« is valid for C/ObjC, but not for C++ [activated by default]
Foo_stub.o: In function `foo':
Foo_stub.c:(.text+0x20): undefined reference to `Foo_zdffoozualy_closure'
Foo_stub.o: In function `stginit_export_Foo_zdffoozualy':
Foo_stub.c:(.text+0x80): undefined reference to `Foo_zdffoozualy_closure'
collect2: ld returned status 1

如何编译?

【问题讨论】:

    标签: c++ haskell g++ ghc ffi


    【解决方案1】:

    试试这个:

    $ ghc --make -no-hs-main main.cpp Foo.hs
    

    我认为问题在于 GHC 认为您传入的存根对象文件只是另一个要正常链接的对象,但您并没有传递 Foo.o 文件本身,因此存根代码没有要链接的内容到!直接传入源文件应该可以解决。 (这只是根据文档和您看到的错误的推测,我没有测试过。)

    我认为你可以像这样单独编译:

    $ ghc --make Foo.hs
    $ ghc --make -no-hs-main main.cpp Foo.o
    

    但我不确定。您可能还想考虑将您的 Haskell 代码构建为 shared library,然后通常使用 g++ 将其链接到您的主程序。

    当您的程序的入口点不是 Haskell 值 Main.main 时,需要-no-hs-main,如您链接的文档中所述。

    【讨论】:

      猜你喜欢
      • 2021-09-15
      • 2022-05-03
      • 2017-07-10
      • 1970-01-01
      • 1970-01-01
      • 2013-08-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多