7

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
danbst
  • 3,363
  • 18
  • 38
  • 3
    It seems that ByteString.Internal does not export the constructor `PS` (with good reason!), so indeed you cannot pattern match on it. Why exactly do you want to get the pointed to the ByteString object? If we know that it will be easier to know how to help. – Tom Ellis Nov 24 '13 at 21:15
  • 2
    `.Internal` does export `PS`. danbst: When asking a question, please include the full code and full error message so that people don't have to guess at what's going wrong. – shachaf Nov 24 '13 at 21:44

1 Answers1

8

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.

Jon Purdy
  • 53,300
  • 8
  • 96
  • 166
  • Thanks, I could not imagine, that pattern match can cause impurity in some cases, so I didn't look through _unsafe_ functions. – danbst Nov 25 '13 at 03:01
  • @danbst: Well, actually *getting* the pointer is pure. But it is impure to pass the pointer to a C function that may mutate it. If you know that such a function is pure, that’s what `unsafePerformIO` is for. It’s a promise to the type system that you know a fact, even though it can’t be proven. – Jon Purdy Nov 25 '13 at 06:46