Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
通过外部导出公开Haskell函数CString的ccall失败_Haskell_Cstring_Ffi - Fatal编程技术网

通过外部导出公开Haskell函数CString的ccall失败

通过外部导出公开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 当我这样做的时

我制作了一个简短的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
当我这样做的时候,它可以编译: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