Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/164.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Haskell中删除对象时调用函数 我正在编写一个C++类的Haskell包装器。我决定把它表示为一个包含指针(Fiel.pTR)的Haskell数据结构,它是C++中的类实例。差不多吧_C++_Haskell_Garbage Collection_Ffi - Fatal编程技术网

在Haskell中删除对象时调用函数 我正在编写一个C++类的Haskell包装器。我决定把它表示为一个包含指针(Fiel.pTR)的Haskell数据结构,它是C++中的类实例。差不多吧

在Haskell中删除对象时调用函数 我正在编写一个C++类的Haskell包装器。我决定把它表示为一个包含指针(Fiel.pTR)的Haskell数据结构,它是C++中的类实例。差不多吧,c++,haskell,garbage-collection,ffi,C++,Haskell,Garbage Collection,Ffi,在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(); } 在哈斯克尔: Data MyClass = MyCla

在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();
}
在哈斯克尔:

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垃圾收集器在某个时候会删除MyC类对象,但是它不会触发MyClass在C++中释放的内存。我该如何解决这个问题

我知道,但它使用了
IO
monad,这并不令人满意,因为我希望包装的数据结构与正常的Haskell数据结构完全一样,而不需要显式分配/释放内存或
IO
monad

“它使用
IO
monad,这并不令人满意,因为我希望包装的数据结构与正常的Haskell数据结构完全一样”

当然,但不幸的是,这不太可能。外国的“功能”总是可以做一些有趣的事情,这在哈斯克尔是不可能的;类型系统无法查看并阻止它

这一困境是我们拥有
unsafePerformIO
的唯一(!)原因,事实上,您的应用程序就是一个很好的例子

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

extern "C" void cpp_delete_MyClass(MyClass* obj) {
    delete obj;
}
foreign import ccall“cpp\u new\u MyClass”cppNewMyClass::IO(Ptr())
外部导入ccall“&cpp_delete_MyClass”cppDeleteMyClass::FunPtr(Ptr()->IO())
数据MyClass=MyClass(ForeignPtr())
mkMyClass::MyClass
mkMyClass=unsafePerformIO$do

你的班级没有副作用吗?如果不是,因为它在C++中是常见的,你必须使用<代码> IO < /Cord>单元格,或者小心地确保你将纯接口暴露给它。这或者失去引用的透明度,这在Haskell中是一个致命的罪过,因为这将使程序的行为几乎无法预测,特别是当优化器假设它重写代码时。@chi是的,它没有副作用。我在
ForeignPtr
上使用
unsafePerformIO
想到了这样的解决方案,但我不确定它是否能正常工作。如果你是,你能解释一下在那个方法后面的场景是什么吗?@每次WWWT(代码< > MKMyCype < /Cord>)被评估(应该只有一次,但不依赖于此)分配一个C++对象,用一个附加的终结器创建一个Haskell值,并返回纯的值。当垃圾收集其中一个值时,将运行终结器(
cppDeleteMyClass
)。声明
cppdetemyclass
的正确方法是
foreign import ccall“&cpp\u delete\u MyClass”cppdetemyclass::FunPtr(Ptr()->IO())
(添加(&D))。你可能应该修正你的答案。如果你想保证
cppNewMyClass
只被调用一次,你应该在
mkMyClass
上加上一条NOINLINE(尽管在这种情况下OP可能不需要这样的保证)。