C Haskell FFI:编译和链接成功,应用程序在BEX64中崩溃

C Haskell FFI:编译和链接成功,应用程序在BEX64中崩溃,c,haskell,ffi,C,Haskell,Ffi,我正在学习如何使用FFI,并从一个非常简单的示例开始,从Haskell调用C函数 这一切都是在Windows7、64位、VisualStudioCommunity 2013下进行的 C看起来像这样: _declspec(dllexport) int line(int m, int b, int x) { return m * x + b; } module Main (main) where foreign import ccall "line" cline :: Int ->

我正在学习如何使用FFI,并从一个非常简单的示例开始,从Haskell调用C函数

这一切都是在Windows7、64位、VisualStudioCommunity 2013下进行的

C看起来像这样:

_declspec(dllexport) int line(int m, int b, int x) {
    return m * x + b;
}
module Main (main) where

foreign import ccall "line" cline :: Int -> Int -> Int -> Int

main = do
    putStr "hello,world\n"
    putStr (show y)

y = cline 2 5 10
我已经将VS编译器设置为生成一个64位DLL,它会这样做,一个名为simplelib.DLL的DLL(还有匹配的.lib文件)

匹配的Haskell如下所示:

_declspec(dllexport) int line(int m, int b, int x) {
    return m * x + b;
}
module Main (main) where

foreign import ccall "line" cline :: Int -> Int -> Int -> Int

main = do
    putStr "hello,world\n"
    putStr (show y)

y = cline 2 5 10
GHC是在上个月7.8.3下载的

ghc的命令行如下所示:

c:\> ghc foreign -L. -lsimpleclib
这将成功运行,并按预期生成.EXE

在BEX64上运行该程序会导致应用程序崩溃:

问题事件名称:BEX64 应用程序名称:foreign.exe 应用程序版本:0.0.0.0 应用程序时间戳:551048a6 故障模块名称:StackHash_0981 故障模块版本:0.0.0.0 故障模块时间戳:00000000 异常偏移量:0000000000000000 异常代码:c0000005 异常数据:0000000000000008 操作系统版本:6.1.7601.2.1.0.256.4 区域设置ID:1033 补充资料1:0981 附加信息2:09817cdf87ca03322f39545f3e74c62d 补充资料3:31c0 附加信息4:31c0a543af0be952ecd86b6ee71cc83a

我还尝试使用Data.Int.Int64作为参数定义。同样的结果

有人有什么想法吗

谢谢,
cww

我找不到告诉VS创建64位dll的旋钮,所以我尝试了gcc(在Win7上,64位)。我必须用两种方法更改c程序的第一行,添加一个
\uuuuCDECL
,并使
\uCDECL
有两个下划线:
\uuuu declspec(dllexport)int\uuu cdecl行(intm,intb,intx){


`

VS生成64位导入库(
.lib
.dll
)实际上是
binutils
中的一个错误。请参阅此处的讨论:


可以通过将GHC发行版中的binutils替换为MSys2中的binutils来解决此问题。或者,链接器通常能够直接链接
.dll
文件,而无需
.lib
文件。这对我来说适用于小示例,但较大的示例可能会失败-我不建议采用此方法。

使用
CInt
,不是
Int
。不确定这是否是唯一的问题,从未尝试链接到windows dll。想法不错。只是尝试了。结果相同。到目前为止,我尝试了Int、CInt、Int32和Int64,认为这可能是某种堆栈未对齐的问题。所有这些都给出了相同的结果。稍微深入查看一下调试器,就会发现根问题lem是(当然)0x0000000000000000(64位0)处的访问冲突。奇怪,因为我看不到任何明显的调整。越来越有趣。我必须读一点gcc上的开关并尝试一下,但我相信它会起作用。因此,在VS中,要构建64位dll,您需要进入配置管理器并添加x64作为配置。因此,当我在“_declspec”所有编译、链接和运行的内容都没有崩溃,只是没有写入任何输出。太奇怪了!如果我注释掉写出y的行,它就会运行,我会收到hello,world消息。有了该行,什么都没有。这台在家机器(仍然是64位Win 7)最初的示例是在工作中进行的。更新:在工作中,它使用gcc构建并运行良好。我不知道Visual Studio编译器/链接器出了什么问题。