在 Haskell 中使用 FFI 到 C++ 时,在 cabal repl
中运行函数时我能够正确捕获异常,但是在使用 cabal run
运行时,异常是没有被抓到。
一个简单的 cabal 项目展示了这个问题如下:
exception.cabal:
name: exception
version: 0.1.0.0
build-type: Simple
cabal-version: >=1.10
executable exception
main-is: Main.hs
c-sources: main.cxx
build-depends: base >=4.7 && <4.8
default-language: Haskell2010
extra-libraries: stdc++
主.cxx:
# include <exception>
# include <stdexcept>
extern "C" int hs_exception() try
{
throw std::logic_error("THIS FAILS!");
} catch(...) {
}
和
Main.hs:
{-# LANGUAGE ForeignFunctionInterface #-}
module Main where
import Foreign.C.Types (CInt(..))
main = print c_hs_exception
foreign import ccall unsafe "hs_exception"
c_hs_exception :: CInt
使用 REPL(即 GHCI):
cabal repl
*Main> main
0
但是当用 GHC 编译并运行时失败:
cabal run
libc++abi.dylib: terminating with uncaught exception of type std::logic_error: THIS FAILS!
[1] 12781 abort cabal run
我的编译器:
➜ gcc --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)
Target: x86_64-apple-darwin13.3.0
Thread model: posix
➜ ghc --version
The Glorious Glasgow Haskell Compilation System, version 7.8.3
最佳答案
这是 Mac 特有的,被报告为 GHC bug 11829 .解决方法是将标记 -lto_library
(LTO = 链接时间优化)传递给 Clang 的链接器。这可以通过 .cabal 文件的可执行部分来完成,如下所示:
executable myprog
...
if os(darwin)
ld-options: -lto_library
如果直接调用 ghc
,则标记 -optl-lto_library
。
请注意,这会错误地建议您改为编写 extra-libraries: to_library
,这是行不通的。
关于c++ - 在 Haskell 中捕获 C++ FFI 异常失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25441526/