- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在用 inline-c
包装一个 C 数值库;一些函数可以将回调传递给步骤例程,考虑 ODE 的优化或时间积分。
特别是在原生 C 中,使用回调可以对连续数组进行操作,通过指针修改它们,并将它们返回到一些不透明(分布式)数据结构。
所以这是一个可变数据问题,我想在 Haskell 方面表示它:在我的理解中,在回调中我们应该卡住数组,处理它,例如作为 Data.Vector.Storable.Vector
或使用 repa
,解卡住果,获取外部指针并将其传回。
内部结构:newtype Vec = Vec (Ptr Vec) deriving Storable
,以及 inline-c
上下文中的相关条目,表示指向一个指针的类型不透明的 C 数据结构和 vecGetArray
/vecRestoreArray
分别生成/请求指向连续内存的相同指针和请求/生成 Vec
。
我注意到,虽然返回的 Vector
是正确的,但当我使用经过修改的结果 Vec
(“副作用”)时,从该函数返回后,它没有被修改。 GHC 不会重新计算它(懒惰?)。我如何让它重新计算它? Haskell 中有什么惯用的方法来处理 FFI 中的可变数据?
查看答案
谢谢!
import qualified Data.Vector.Storable as V
import qualified Data.Vector.Storable.Mutable as VM
withVecGetVectorM ::
Vec ->
(V.Vector PetscScalar_ -> IO (V.Vector PetscScalar_)) ->
IO (V.Vector PetscScalar_)
withVecGetVectorM v f = do
p <- vecGetArrayPtr v
pf <- newForeignPtr_ p
vImm <- V.freeze (VM.unsafeFromForeignPtr0 pf len)
vImmOut <- f vImm
vMutOut <- V.thaw vImmOut
let (fpOut, _, _) = VM.unsafeToForeignPtr vMutOut
pOut = unsafeForeignPtrToPtr fpOut
vecRestoreArrayPtr v pOut
return vImmOut
where len = vecSize v
Vec.hs :
vecGetArrayPtr :: Vec -> IO (Ptr PetscScalar_)
vecGetArrayPtr v = chk1 (vecGetArrayPtr' v)
vecRestoreArrayPtr :: Vec -> Ptr PetscScalar_ -> IO ()
vecRestoreArrayPtr v ar = chk0 (vecRestoreArrayPtr' v ar)
内联C.hs
-- PETSC_EXTERN PetscErrorCode VecGetArray(Vec,PetscScalar**);
vecGetArrayPtr' :: Vec -> IO (Ptr PetscScalar_, CInt)
vecGetArrayPtr' v = withPtr $ \p -> vga v p where
vga v p = [C.exp|int{VecGetArray($(Vec v), $(PetscScalar** p))}|]
-- PETSC_EXTERN PetscErrorCode VecRestoreArray(Vec,PetscScalar**);
vecRestoreArrayPtr' :: Vec -> Ptr PetscScalar_ -> IO CInt
vecRestoreArrayPtr' v c = with c $ \pc -> vra v pc
where
vra w pc = [C.exp|int{VecRestoreArray($(Vec w), $(PetscScalar** pc))}|]
此外,IIUC,该代码制作了 2 个额外的矢量副本,一个在卡住时,一个在解冻时。 ,但我怀疑它效率低下。有人可以提出改进或简化建议吗?
最佳答案
我犯了一个微不足道的错误。要处理的指针;这是解决方法。这个函数与有问题的函数有相同的签名,这表明我必须有一种类型化的方式来表示我们正在修改哪个指针。如果有人对此有任何建议,请随时与我们联系。
vecRestoreVector :: Vec -> V.Vector PetscScalar_ -> IO ()
vecRestoreVector v w = do
p <- vecGetArrayPtr v
pf <- newForeignPtr_ p
V.copy (VM.unsafeFromForeignPtr0 pf len) w
vecRestoreArrayPtr v p
where
len = vecSize v
关于haskell - FFI 中的可变数据和惰性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33418831/
我正在努力通过接受 void 的 FFI 传递结构并在另一端读回它。 有问题的库是 libtsm,一个终端状态机。它允许您提供输入,然后找出输入后终端将处于哪种状态。 它将其绘制函数声明为: pub
只是为了测试目的,我在 delphi 中创建了一个小的 DLL。代码为: library MyDll; uses SysUtils, Classes, Vcl.Dialogs;
这是我一直好奇的事情:我想知道 LuaJIT 的 FFI 模块如何设法使用正确的调用约定来调用外部 native 函数,而无需在用户原型(prototype)中进行任何声明。 我尝试阅读源代码以自己解
我有一个带有函数的 C 库,在一个不透明的结构上运行,定义如下: Foo* makeFoo(); // create a new Foo Foo* dupFoo(const Foo* orig); /
我正在尝试从 purescript 调用 navigator.geolocation.getCurrentPosition javascript 函数,但遇到了两个问题。 在 javascript 中
ruby 版本 2.2.4p230 RubyGem 版本 2.7.2 已安装 Ruby-devel 和 lib64ffi-devel。 使用 64 位 OpenMandriva 3.0、urpmi 和
我正在尝试使用 FFI 将以下 JavaScript 函数导入 PureScript: function getGreeting() { return "Hi, welcome to the sh
我对 Haskell 中的 FFI 有一些疑问 我知道我必须使用语言编译指示 {-# LANGUAGE ForeignFunctionInterface #-}但是当我使用 {-# LANGUAGE
当我尝试构建 Flutter项目至 IOS 它向我显示了这个错误,我尝试清理并尝试更改项目的目录。 Launching lib/main.dart on iPhone 12 Pro Max in de
完整堆栈跟踪: /Users/galharth/.rvm/gems/ruby-2.3.0/gems/activesupport-4.2.5/lib/active_support/dependencie
我试过运行 pod install在我的 Xcode 项目中,但出现以下错误 /System/Library/Frameworks/Ruby.framework/Versions/2.6/us
我需要在节点 Electron 项目中使用模块“ffi”。我可以使用“gyp”重建它并在节点中使用库,但我不能使用“electron-rebuild”重建它并在 Electron 中使用它。 我跑了:
以下警告是什么意思,我该如何解决它的原因? Warning: Unimplemented primitive used:removeEventListener 在 [@bs.val] external
谁能告诉我一个使用带有可变参数的 C 函数(例如 printf )和 Haskell 的外部函数接口(interface)的示例?我尝试搜索 HaskellWiki,但没有找到这样的示例。 谢谢! 最
我使用 FFI 是为了在 C 中使用一个函数,该函数接受一个结构并返回相同的结构。我看到的引用说我必须使用指向这些结构的指针才能将其导入 Haskell。所以,例如。 data Bar = Bar {
我想在带有 FFI 的 Rust 中包含一个动态 C 库。 该库实际上也是用 Rust 构建的,但公开了一个 C 接口(interface),因此它也可以从其他语言中使用。当我用 cargo 构建库(
我试图在winapi上写一个包装器。我想包装接受回调函数指针的函数。 例如,考虑以下情况: // The unsafe callback type the FFI function accepts t
我正在使用 rust-bindgen 从 Rust 访问 C 库。一些函数返回指向结构的可空指针,bindgen 表示为 extern "C" { pub fn get_some_data()
介绍 我正在用 inline-c 包装一个 C 数值库;一些函数可以将回调传递给步骤例程,考虑 ODE 的优化或时间积分。 特别是在原生 C 中,使用回调可以对连续数组进行操作,通过指针修改它们,并将
fn main() { let val = 0; unsafe { foo(&val) } } extern "C" { pub fn foo(val: *const u32)
我是一名优秀的程序员,十分优秀!