c - 如何使用 Haskell 的 C 库?
问题描述
我正在尝试使用 FFI 从 Haskell 调用 C 函数,但我不断收到此错误:
ghc.exe:^^ 无法加载“getSize”,未解决依赖关系。请参阅上面的顶部条目。
main: ByteCodeLink: can't find label 在交互式链接过程中,GHCi 找不到以下符号:getSize 这可能是由于您没有要求 GHCi 加载当前会话所需的额外目标文件、档案或 DLL。重新启动 GHCi,使用 -L/path/to/object/dir 和 -lmissinglibname 标志指定缺少的库,或者简单地通过在 GHCi 命令行上命名相关文件。或者,此链接失败可能表明 GHCi 中存在错误。如果您怀疑后者,请将错误报告发送至:
glasgow-haskell-bugs@haskell.org
我stdio.h
在我的 C 库中使用该库:
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
PS这可能是因为我也必须在stdio.h
其他地方指定依赖关系吗?
解决方案
好的,这里有几件事要做:
- 将“lib.h”重命名为“lib.c”。它是 C 源文件(包含代码),而不是 C 头文件。
- 理想情况下,添加一个单独的“lib.h”头文件,其中包含
getSize
. - 修复“lib.c”中的错误。您希望用 "%lf" 代替 "$f" 来读取双精度。
- 编译程序
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 ...
然后你可以运行它,为 HaskellgetLine
提供一行,为 C 提供第二行scanf
,它应该可以正常工作:
$ ./Main
hello world!! -- line for Haskell
135.0 -- line for C
"got from C: 135.0"
推荐阅读
- python - 哎呀。正确传递参数
- python - Python:使用 curses 库打印 ASCII 文本文件
- python - 在计算两个排序数组的中位数时,是否有较小的数组驱动二进制搜索?
- javascript - 如何在谷歌脚本中总结从今天开始的 7 天?
- swiftui - 如何在 SwiftUI 中设置自定义环境键?
- javascript - 在 Vuex 中更新状态?
- docker - 为什么我不能在 Dockerfile 中运行命令,但我可以在我的 Docker 容器中运行?
- excel - 基于范围的窗口计数和概率
- ios - 连接插座的 NS Unknown Key 异常
- networking - 如何确定未知网络上的 IPv4 设置?