在 ghci 中从 c 源调用动态库失败
Calling dynamic libraries from c-sources fails in ghci
我有一些动态库中的 C 函数(这里只是 zlibVersion
),我想从 cabal 包中的捆绑 C 代码调用这些函数。在这里,我将其直接称为外部导入,并通过捆绑的 C 代码间接调用它,以表明后者会导致 ghci 崩溃,即使在前者成功之后也是如此。
Main.hs:
module Main (main) where
import Foreign.C.String (CString, peekCString)
foreign import ccall "foreign_test" foreignTest :: IO ()
foreign import ccall "zlibVersion" zlibVersion :: IO CString
main :: IO ()
main = do
zlibVersion >>= peekCString >>= putStrLn
foreignTest
foreign_test.c:
#include <stdio.h>
#include <zlib.h>
void foreign_test() {
puts(zlibVersion());
}
它在编译后的二进制文件中运行良好:
$ cabal build
$ dist/build/cabal-extra-libs-test/cabal-extra-libs-test
1.2.5
1.2.5
但是间接调用崩溃了 ghci:
$ cabal repl
Preprocessing executable 'cabal-extra-libs-test' for
cabal-extra-libs-test-0.1.0.0...
GHCi, version 7.10.3: http://www.haskell.org/ghc/ :? for help
[1 of 1] Compiling Main ( Main.hs, interpreted )
Ok, modules loaded: Main.
*Main> main
1.2.5
dyld: lazy symbol binding failed: Symbol not found: _zlibVersion
Referenced from: /var/folders/pz/920gzhqn01q8d6vjkvy1yvdr0000gn/T/ghc6850_0/libghc_1.dylib
Expected in: flat namespace
dyld: Symbol not found: _zlibVersion
Referenced from: /var/folders/pz/920gzhqn01q8d6vjkvy1yvdr0000gn/T/ghc6850_0/libghc_1.dylib
Expected in: flat namespace
cabal-extra-libs-test.cabal:
name: cabal-extra-libs-test
version: 0.1.0.0
build-type: Simple
cabal-version: >=1.10
executable cabal-extra-libs-test
default-language: Haskell2010
main-is: Main.hs
build-depends: base
c-sources: foreign_test.c
extra-libraries: z
GHC 是 7.10.3,在 OS X 10.11.5 上安装了 cabal-install 1.24.0.0。使用 stack 和 stack ghci 构建会产生相同的崩溃。
这很奇怪.. 我对 OSX 了解不多,但 dyld: lazy symbol binding failed: Symbol not found: _zlibVersion
给人的印象是它认为 OSX 是一个下划线平台(例如,C 函数与一个 _)。
这是标准的 GHC 版本吗?你可以试试 8.0.1
吗?链接器中有很多更改。
我有一些动态库中的 C 函数(这里只是 zlibVersion
),我想从 cabal 包中的捆绑 C 代码调用这些函数。在这里,我将其直接称为外部导入,并通过捆绑的 C 代码间接调用它,以表明后者会导致 ghci 崩溃,即使在前者成功之后也是如此。
Main.hs:
module Main (main) where
import Foreign.C.String (CString, peekCString)
foreign import ccall "foreign_test" foreignTest :: IO ()
foreign import ccall "zlibVersion" zlibVersion :: IO CString
main :: IO ()
main = do
zlibVersion >>= peekCString >>= putStrLn
foreignTest
foreign_test.c:
#include <stdio.h>
#include <zlib.h>
void foreign_test() {
puts(zlibVersion());
}
它在编译后的二进制文件中运行良好:
$ cabal build
$ dist/build/cabal-extra-libs-test/cabal-extra-libs-test
1.2.5
1.2.5
但是间接调用崩溃了 ghci:
$ cabal repl
Preprocessing executable 'cabal-extra-libs-test' for
cabal-extra-libs-test-0.1.0.0...
GHCi, version 7.10.3: http://www.haskell.org/ghc/ :? for help
[1 of 1] Compiling Main ( Main.hs, interpreted )
Ok, modules loaded: Main.
*Main> main
1.2.5
dyld: lazy symbol binding failed: Symbol not found: _zlibVersion
Referenced from: /var/folders/pz/920gzhqn01q8d6vjkvy1yvdr0000gn/T/ghc6850_0/libghc_1.dylib
Expected in: flat namespace
dyld: Symbol not found: _zlibVersion
Referenced from: /var/folders/pz/920gzhqn01q8d6vjkvy1yvdr0000gn/T/ghc6850_0/libghc_1.dylib
Expected in: flat namespace
cabal-extra-libs-test.cabal:
name: cabal-extra-libs-test
version: 0.1.0.0
build-type: Simple
cabal-version: >=1.10
executable cabal-extra-libs-test
default-language: Haskell2010
main-is: Main.hs
build-depends: base
c-sources: foreign_test.c
extra-libraries: z
GHC 是 7.10.3,在 OS X 10.11.5 上安装了 cabal-install 1.24.0.0。使用 stack 和 stack ghci 构建会产生相同的崩溃。
这很奇怪.. 我对 OSX 了解不多,但 dyld: lazy symbol binding failed: Symbol not found: _zlibVersion
给人的印象是它认为 OSX 是一个下划线平台(例如,C 函数与一个 _)。
这是标准的 GHC 版本吗?你可以试试 8.0.1
吗?链接器中有很多更改。