使用C ++中的haskell函数:未定义的引用错误 [英] Using a haskell function from C++: Undefined reference error

查看:173
本文介绍了使用C ++中的haskell函数:未定义的引用错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从C ++中调用haskell函数,并在 http://www.haskell.org/ghc/docs/7.0.2/html/users_guide/ffi-ghc.html

I want to call haskell functions out of C++ and did use the tutorial at http://www.haskell.org/ghc/docs/7.0.2/html/users_guide/ffi-ghc.html

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

So I have a haskell file 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))

并称为

and called

ghc Foo.hs

创建了一个Foo_stub.h:

which created a Foo_stub.h:

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

a Foo_stub。 c:

a 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文件。

It also created a Foo_stub.o file.

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

I now created a main.cpp file:

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

并试图编译它。

使用g ++失败:

Using g++ failed:

$ 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。但这也失败了:

so I tried ghc --make. But this also failed:

$ 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

我如何编译它?

How can I compile it?

推荐答案

试试这个:

Try this:

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

我相信问题在于GHC认为你传入的存根目标文件是只是另一个要正常链接的对象,但是你没有传递 Foo.o 文件本身,所以存根代码没有任何可链接的东西!直接传入源文件应该可以解决它。 (这只是基于文档和你看到的错误的猜测,我还没有测试过。)

I believe the problem is that GHC thinks the stub object file you're passing in is just another object to be linked normally, but you're not passing the Foo.o file itself, so the stub code has nothing to link to! Passing in the source file directly should solve it. (This is just conjecture based on the documentation and the error you're seeing, I haven't tested it.)

我认为你可以这样分开编译:

I think you could do separate compilation like this:

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

但我不确定。您可能还想考虑将您的Haskell代码构建到共享库,然后通过 g ++ 将其链接到主程序。

but I'm not sure. You might also want to look into building your Haskell code into a shared library, and then linking it to your main program normally with g++.

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

-no-hs-main is required when your program's entry point isn't the Haskell value Main.main, as described in the documentation you linked.

这篇关于使用C ++中的haskell函数:未定义的引用错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆