我做了一个简短的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 ??
答案 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 #-}
导入也可能有效