c - 如何使用 Haskell 的 C 库?

标签 c haskell interop ffi

我正在尝试使用 FFI 从 Haskell 调用 C 函数,但我不断收到此错误:

ghc.exe: ^^ Could not load 'getSize', dependency unresolved. See top entry above.

main: ByteCodeLink: can't find label During interactive linking, GHCi couldn't find the following symbol: getSize This may be due to you not asking GHCi to load extra object files, archives or DLLs needed by your current session. Restart GHCi, specifying the missing library using the -L/path/to/object/dir and -lmissinglibname flags, or simply by naming the relevant files on the GHCi command line. Alternatively, this link failure might indicate a bug in GHCi. If you suspect the latter, please send a bug report to:
glasgow-haskell-bugs@haskell.org

我在我的 C 库中使用 stdio.h 库:

C 库

// lib.h
#include <stdio.h>

double getSize() {
    double size = 0;
    scanf("$f", &size);
    return size;
}

FFI模块

{-# LANGUAGE ForeignFunctionInterface #-}
module Ffi where

import Foreign
import Foreign.C.Types

foreign import ccall "lib.h getSize" c_size :: IO Double

主要

module Main where
import Ffi

main :: IO ()
main = do a <- getLine
          b <- c_size
          print $ "got from C: " ++ show b

运行脚本

gcc -o lib -lib.h
runghc main

P.S. 这可能是因为我不得不在其他地方指定依赖项 stdio.h 吗?

最佳答案

好了,这里有几件事情要做:

  • 将“lib.h”重命名为“lib.c”。它是 C 源文件(包含代码),而不是 C 头文件。
  • 理想情况下,添加一个单独的“lib.h”头文件,其中包含 getSize 的原型(prototype)。
  • 修复“lib.c”中的错误。您希望用“%lf”代替“$f”以读成 double 。
  • 使用ghc 编译程序而不是使用runghc 运行程序。单个 ghc 命令可以编译和链接 Haskell 模块和 C 代码。

换句话说,您的文件应该如下所示:

// lib.c
#include "lib.h"
#include <stdio.h>
double getSize() {
    double size = 0;
    scanf("%lf", &size);
    return size;
}
// lib.h
double getSize(void);
-- Ffi.hs
{-# LANGUAGE ForeignFunctionInterface #-}
module Ffi where
import Foreign
import Foreign.C.Types
foreign import ccall "lib.h getSize" c_size :: IO Double
-- Main.hs
module Main where
import Ffi
main :: IO ()
main = do a <- getLine
          b <- c_size
          print $ "got from C: " ++ show b

你应该编译它:

$ ghc Main.hs lib.c
[1 of 2] Compiling Ffi              ( Ffi.hs, Ffi.o )
[2 of 2] Compiling Main             ( Main.hs, Main.o )
Linking Main ...

然后您可以运行它,为 Haskell getLine 提供一行,为 C scanf 提供第二行,它应该可以正常工作:

$ ./Main
hello world!!   -- line for Haskell
135.0           -- line for C
"got from C: 135.0"

关于c - 如何使用 Haskell 的 C 库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56512208/

相关文章:

c - 如何避免枚举值的冲突?

c# - 如何从非托管应用程序获取文本到 C# 应用程序?

c# - PCWSTR 与 LPWSTR

c - 为什么这个数组现在不能正确输出,即使它在早期的测试中工作得很好

python - 如何使用 Ctypes 将此 numpy 数组传递给 C?

haskell - 与 Travis CI 堆叠

haskell - 这个和KleisliFunctor类似的东西是什么?

haskell - 打印自由单子(monad)

wcf - WCF 客户端的 WSSecurity IBM DataPower 问题

c - 如何为堆栈实现调试此 C 代码?