通过外部导出公开Haskell函数ccall对CStrings失败

时间:2011-07-21 21:35:24

标签: haskell cstring ffi

我做了一个简短的Haskell程序,它公开了C或Python的函数。跟着http://www.haskell.org/ghc/docs/7.0.3/html/users_guide/ffi-ghc.html#ffi-library跟着这封信,这对于出口Ints也没问题。

想要导出字符串并制作程序:

module Adder where

import CString

adder :: Int -> Int -> IO CString 
adder x y =  newCString(show(x+y))

foreign export ccall adder :: Int -> Int -> IO CString

当我这样做时编译好了:ghc adder.hs 但在链接到Windows中创建dll时失败。

  

ghc -shared -o adder.dll adder.o adder_stub.o StartEnd.o

错误: adder.o:fake :(。text + 0x11d):未定义引用`__stginit_haskell98zm1zi1zi0zi1_CString _'

StartEnd.o是从我从haskell.org网站复制的C文件编译的:

#include <Rts.h>
extern void __stginit_Adder(void);
void HsStart()
{
  int argc = 1;
  char* argv[] = {"ghcDll", NULL}; // argv must end with NULL
  // Initialize Haskell runtime
  char** args = argv;
  hs_init(&argc, &args);
  // Tell Haskell about all root modules
  hs_add_root(__stginit_Adder);
}
void HsEnd()
{
  hs_exit();
}

我该怎么做才能导出Strings ??

1 个答案:

答案 0 :(得分:2)

尝试导入Foreign.C.String而不是模块CString。 GHC应该识别正确库中的模块和链接。在Linux系统上编译静态,我遇到了同样的问题(undefined ref)。当我改变了那个导入,给我下面的代码,一切都有效。

我的Haskell模块(导出函数):

$ cat so.hs
module Adder where

import Foreign.C.String

adder :: Int -> Int -> IO CString 
adder x y =  newCString(show(x+y))

foreign export ccall adder :: Int -> Int -> IO CString

我的主要C文件(包括所有init和内联工作,不是很漂亮,但这只是教育):

$ cat soMain.c
#include <Rts.h>
#include "so_stub.h"

extern void __stginit_Adder(void);

void main()
{
  char *str = NULL;
  int argc = 1;
  char* argv[] = {"ghcDll", NULL}; // argv must end with NULL
  // Initialize Haskell runtime
  char** args = argv;
  hs_init(&argc, &args);
  // Tell Haskell about all root modules
  hs_add_root(__stginit_Adder);

  // END INIT


  str = adder(1,2);
  printf("%s\n",str);

  // END MAIN START THE FINALIZERS
  hs_exit();


}

我的命令:

$ ghc -c so.hs
$ ghc soMain.c so_stub.o so.o -o so -fforce-recomp
$ ./so
3

编辑:只是一个猜测,但如果您指定CString

{-# LANGUAGE Haskell98, ForeignFunctionInterface #-}导入也可能有效