Moja sprawa jest dość prosta: mam aplikację C++ i bibliotekę Haskell, i muszę wyeksportować z Haskella funkcję, która zwróci ciąg znaków C.Jaki jest właściwy sposób zarządzania przydzieloną pamięcią w obcym języku?
Problem jest, że ciąg C jest pierwotnie String
, i aby uzyskać ciąg C z niego muszę przydzielić pamięci, które będą musiały być wyraźnie dealokowane (Haskell na free
lub finalizerFree
, jako dokumentacja dla newCString
mówi) .
Co to jest dobry sposób na rozwiązanie tego problemu? W szczególności mam kilka uwag:
Idealnie chciałbym w jakiś sposób pozwolić na to, aby Gask wykonawczy Haskell je obsłużył, ale nie jestem pewien, jak to możliwe, aby wiedzieć, kiedy i kiedy pamięć jest nadal potrzebna strona obca. Czy to możliwe?
Jeśli nie, czy mogę po prostu zadzwonić do C free
lub jest przechowywany CString
utrzymywany przez środowisko wykonawcze Haskell? jeśli nie, to przypuszczam, że będę musiał wyeksportować Haskella do wersji free
i zadzwonić do niego z zagranicy, zgadza się?
'CString' to tylko alias dla gołego wskaźnika. Haskell nie będzie zarządzał pamięcią dla ciebie. Możesz zbudować [ForeignPtr] (https://hackage.haskell.org/package/base/docs/Foreign-ForeignPtr.html), jeśli chcesz, ale wymaga to trochę ostrożności. Za każdym razem, gdy używasz wskaźnika, musi on być całkowicie zawarty w wywołaniu ['withForeignPtr'] (https://hackage.haskell.org/package/base/docs/Foreign-ForeignPtr.html#v:withForeignPtr). – Rufflewind
Jeśli ciąg nie jest zbyt duży (i nie zmienia się), lepiej byłoby skopiować go tak, aby jedna kopia była własnością strony zagranicznej, a druga kopia jest własnością środowiska wykonawczego Haskell. W przeciwnym razie możesz pomyśleć o tym, że obce strony przekazują własność tego ciągu do Haskella, tj. Strona obca nie zachowuje żadnych odniesień do pamięci, a jeśli musi coś zrobić, to wraca do Haskella, aby to zrobić. –