C Haskell FFI:编译和链接成功,应用程序在BEX64中崩溃
我正在学习如何使用FFI,并从一个非常简单的示例开始,从Haskell调用C函数 这一切都是在Windows7、64位、VisualStudioCommunity 2013下进行的 C看起来像这样: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 ->
_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编译器/链接器出了什么问题。