gpt4 book ai didi

c++ - 在 Haskell 中删除对象时调用函数

转载 作者:可可西里 更新时间:2023-11-01 17:50:26 25 4
gpt4 key购买 nike

我正在为 C++ 类编写 Haskell 包装器。我决定将其表示为包含指向 C++ 类实例的指针 (Foreign.Ptr) 的 Haskell 数据结构。像那样的东西。

在 C++ 中:

class MyClass {
public:
double my_method();

// ...
};

extern "C" MyClass* cpp_new_MyClass() {
return new MyClass();
}

extern "C" double cpp_my_method(MyClass *obj) {
return obj->my_method();
}

在 Haskell 中:

Data MyClass = MyClass (Ptr ())

foreign import ccall "cpp_new_MyClass" cppNewMyClass :: Ptr ()
foreign import ccall "cpp_my_method" cppMyMethod :: Ptr () -> Double

mkMyClass :: MyClass
mkMyClass = MyClass cppNewMyClass

myMethod :: MyClass -> Double
myMethod (MyClass ptr) = cppMyMethod ptr

问题是,我不知道如何正确实现 MyClass 删除。在某些时候,Haskell 垃圾收集器会删除 MyClass 对象,但不会触发 C++ 中的 MyClass* 内存释放。我该如何解决?

我知道 ForeignPtr ,但它使用 IO monad,这并不令人满意,因为我希望包装数据结构的行为与普通的 Haskell 数据结构完全一样,而不需要显式分配/释放内存或 IO 单子(monad)。

最佳答案

“it uses IO monad, which is not satisfying because I want the wrapped data structure to behave exactly as a normal Haskell data structure”

当然可以,但遗憾的是这不太可能。外来“函数”总是可以做 Haskell 不可能做的有趣的事情;类型系统无法查看并阻止它。

这种困境是我们拥有 unsafePerformIO 的唯一 (!) 原因,事实上,您的应用是该事物的有效应用的一个很好的例子。

我自己还没有这样做,但是您的代码应该如下所示:

extern "C" void cpp_delete_MyClass(MyClass* obj) {
delete obj;
}
foreign import ccall "cpp_new_MyClass" cppNewMyClass :: IO (Ptr ())
foreign import ccall "&cpp_delete_MyClass" cppDeleteMyClass :: FunPtr (Ptr () -> IO ())

data MyClass = MyClass (ForeignPtr ())

mkMyClass :: MyClass
mkMyClass = unsafePerformIO $ do
newObj <- cppNewMyClass
fPtr <- newForeignPtr cppDeleteMyClass newObj
return $ MyClass fptr

我不太确定那些 FunPtr,希望有人会对此发表评论...

关于c++ - 在 Haskell 中删除对象时调用函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32313195/

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