通过外部导出公开Haskell函数CString的ccall失败
我制作了一个简短的Haskell程序,它公开了C或Python的函数。严格按照规定执行,这对导出INT很有效 要导出字符串并生成程序:通过外部导出公开Haskell函数CString的ccall失败,haskell,cstring,ffi,Haskell,Cstring,Ffi,我制作了一个简短的Haskell程序,它公开了C或Python的函数。严格按照规定执行,这对导出INT很有效 要导出字符串并生成程序: 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 当我这样做的时
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:false:(.text+0x11d):未定义对“\u stginit\u haskell98zm1zi1zi0zi1\u 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();
}
#包括
外部无效(无效)加法器(无效);;
void HsStart()
{
int argc=1;
char*argv[]={“ghcDll”,NULL};//argv必须以NULL结尾
//初始化Haskell运行时
字符**args=argv;
hs_init(&argc,&args);
//告诉Haskell有关所有根模块的信息
hs_add_root(u stginit_Adder);
}
void HsEnd()
{
hs_退出();
}
我必须做什么才能导出字符串???尝试导入
Foreign.C.String
而不是模块CString
。GHC应识别正确库中的模块和链接。在Linux系统上编译static时,我遇到了与您相同的问题(未定义的ref)。当我修改了导入,留下下面的代码时,一切都正常了
My Haskell模块(导出函数):
我的主C文件(包括所有的初始化和内联工作,不漂亮,但这只是教育性的):
编辑:只是一个猜测,但是如果您指定了
{-#LANGUAGE Haskell98,ForeignFunctionInterface#-}
,那么导入CString
可能会起作用。请注意,我会避免使用f(g(x))样式,并使用f(gx)
或f$gx
或f。g$x
谢谢,这很有帮助。另外,我最近添加了一个自动导出haskell函数的包,可以在中找到它,即使您不想使用它,也可以查看FFI代码的外观。(使用-T保存中间文件)
$ 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
$ 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