Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get Ptr of a ByteString?

Is there a way to extract underlying direct pointer to memory off the ByteString object? My current approach is incorrect, compiler says.

getPtr :: ByteString -> Ptr Word8
getPtr (PS ptr _ _) = ptr
like image 717
danbst Avatar asked Nov 24 '13 20:11

danbst


1 Answers

Use unsafeUseAsCString from Data.ByteString.Unsafe. It has type:

ByteString -> (CString -> IO a) -> IO a

You could use unsafeUseAsCString bs return to simply get the pointer, but this is highly unsafe because the ByteString isn’t guaranteed not to move, and the memory may be freed at any point after the CString -> IO a function terminates, so you should only access the pointer within it; internally it uses Foreign.ForeignPtr.withForeignPtr, which pins the memory so it won’t move if a GC happens. Per the docs:

The memory may freed at any point after the subcomputation terminates, so the pointer to the storage must not be used after this.

The string also won’t be null-terminated unless the ByteString happened to be, and it will have type CString (that is, Ptr CChar) instead of Ptr Word8, but you can use castPtr from Foreign.Ptr to get around that if it’s a problem.

like image 84
Jon Purdy Avatar answered Oct 16 '22 23:10

Jon Purdy