gpt4 book ai didi

python - 与 Python 相比,在 Haskell 中调用 c 函数

转载 作者:太空狗 更新时间:2023-10-30 03:01:30 27 4
gpt4 key购买 nike

在 Python 中我可以这样做:

import ctypes
import ctypes.util

my_lib = ctypes.cdll.LoadLibrary (ctypes.util.find_library ('my_lib') or 'my_lib32')
a = my_lib.some_function(33)
b = my_lib.some_function2(33)
c = my_lib.SOME_CONST_123

而且由于我需要将这种类型的 Python 代码转换为 Haskell,我想知道我是否可以在 Haskell 中做同样的事情?我知道我可以通过 FFI 做类似的事情。但这并不是我在 Python 中可以做的,因为就我在 Haskell 中所关心的而言,我必须首先声明函数,如下所示:

foreign import ccall "my_lib.h some_function"
some_function :: CDouble -> CDouble

是这样吗,有没有更简单的方法?

最佳答案

Python 中的 ctypes 库基本上是 C 库 libffi 的包装器,它是一个让我们在运行时而不是编译时给定信息的进程地址空间中调用任意函数的库。

same library可以在 Haskell 中与动态链接器一起使用以达到相同的效果:

import Foreign.LibFFI
import System.Posix.DynamicLinker

example :: IO ()
example = do
dlopen "mylib.so" [RTLD_LAZY]
fn <- dlsym Default "some_function"
fn2 <- dlsym Default "some_function2"
a <- callFFI fn retCInt [argCInt 33]
b <- callFFI fn2 retCInt [argCInt 33]
return ()

由于很多原因,这并不理想,而且我不建议构建大量这样的绑定(bind),原因与许多 Python 开发人员不赞成使用 ctypes 进行绑定(bind)的原因相同,除非作为最后的手段。首先,它会为每个函数调用带来一些开销(与 ctypes 的开销大致相同)。与来自 Haskell 的 ccall unsafe FFI 函数相比 has basically no overhead并且与本地 C 函数调用一样便宜。

其次,不再使用简单的 Haskell 类型参数,例如 IntFloat 函数参数现在都在一个巨大的 libffi 和类型 Arg 这对类型系统是不透明的,很容易引入细微的错误。

如果您可以在编译时链接 C 库并转发声明函数,无论是使用常规的 Haskell FFI (-XForeignFunctionInterface) 和/或像 c2hs 这样的工具,这将使生活变得更加轻松。

关于python - 与 Python 相比,在 Haskell 中调用 c 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25093052/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com