2015-01-22 2 views
9

Мое дело довольно просто: у меня есть приложение C++ и библиотека Haskell, и мне просто нужно экспортировать из Haskell функцию, которая вернет строку C.Каков правильный способ управления выделенной памятью на иностранном языке?

Вопрос заключается в том, что строка С первоначально String, и, чтобы получить строку C из этого мне нужно выделить память, которая будет иметь, чтобы быть явно высвобождены (Хаскель free или finalizerFree, как документация newCString говорит) ,

Что такое хороший способ справиться с этим? В частности, у меня есть несколько соображений:

В идеале я хотел бы как-то позволить GC GC Haskell обрабатывать это, но я не уверен, как он мог знать, когда и когда не требуется память, иностранная сторона. Является ли это возможным?

Если нет, могу ли я просто позвонить C free или это CString хранилище, поддерживаемое операцией Haskell? если нет, я полагаю, мне придется экспортировать Haskell's free как-хорошо и назвать его с внешней стороны, правильно?

+1

'CString' - просто псевдоним для голого указателя. Haskell не будет управлять своей памятью для вас. Вы можете построить [ForeignPtr] (https://hackage.haskell.org/package/base/docs/Foreign-ForeignPtr.html), если хотите, но это требует некоторой осторожности. Каждый раз, когда вы используете указатель, он должен содержаться полностью в вызове ['withForeignPtr'] (https://hackage.haskell.org/package/base/docs/Foreign-ForeignPtr.html#v:withForeignPtr). – Rufflewind

+0

Если строка не слишком велика (и не мутирует), возможно, вам лучше скопировать ее, чтобы одна копия принадлежала другой стороне, а другая копия принадлежала среде исполнения Haskell. В противном случае вам может понадобиться подумать о том, что иностранная сторона передает права собственности на строку в Haskell, то есть внешняя сторона не сохраняет никаких ссылок на память, и если ей нужно что-либо сделать, она обращается к Haskell для этого. –

ответ

1

Вы должны освободить строку: как вы говорите, GC GC Haskell не знает, может ли это по-прежнему нуждаться в иностранной стороне.

Haskell's free в точности соответствует C free. Вы можете позвонить либо с той стороны, которую вы предпочитаете.

free :: Ptr a -> IO() 
free = _free 

foreign import ccall unsafe "stdlib.h free" _free :: Ptr a -> IO() 

Я не проверял, если это предусмотрено в докладе Haskell + FFI Дополнением, но я так думаю.

+1

Можно также использовать 'pokeArray' с буфером с внешним распределением, чтобы быть в безопасности. – Rufflewind

+1

«Свободный» Haskell в точности эквивалентен «свободному» C - Это может быть правдой, но забота в порядке. См. Http://blog.haskell-exists.com/yuras/posts/malloc-free-and-ffi.html. –