Tôi đang cố gắng tạo trình bao bọc Haskell cho thư viện C. Các cấu trúc cơ bản quá phức tạp để thể hiện như các kiểu tường minh, và tôi không thực sự sử dụng chúng ngoài việc chuyển giữa các hàm C, vì vậy tôi đang sử dụng EmptyDataDecls
để cho GHC làm việc đó cho tôi.Tuyên bố dữ liệu rỗng đáng yêu
Điều tôi cần là con trỏ đến một trong các loại dữ liệu này, nhưng khi tôi cố tạo một kiểu với alloca
, nó sẽ than phiền rằng dữ liệu không thuộc loại Storable
. Ví dụ:
{-# LANGUAGE ForeignFunctionInterface, EmptyDataDecls #-}
module Main where
import Foreign.Marshal.Alloc
import Foreign.Ptr
data Struct
foreign import ccall "header.h get_struct"
get_struct :: Ptr Struct -> IO()
main = alloca $ \ptr -> get_struct ptr
GHC sẽ không biên dịch điều này, không có trường hợp nào cho số Storable Struct
. Tôi có thể tự mình thực hiện:
instance Storable Struct where
sizeOf _ = ...
alignment _ = ...
Nhưng điều đó gần như đánh bại mục đích - tôi không muốn phải xác định những điều như vậy nếu tôi không quan tâm đến cấu trúc.
Tôi nhận thấy rằng con trỏ trỏ đến hoạt động tốt, vì lớp Ptr
là Storable
. Vì vậy, tôi có thể thực hiện những gì tôi đang nhắm đến bằng cách sử dụng peek
trên ptr
trước khi gọi get_struct
:
main = alloca $ \ptr -> do
ptr <- peek ptr
get_struct ptr
này cảm thấy giống như một hack, mặc dù.
Có cách nào để nhận các khai báo dữ liệu trống để được coi là Storable
mà không định nghĩa một cá thể không?
Đây là một hack. Bạn không bao giờ phân bổ không gian cho con trỏ bên trong; bạn chỉ đang trỏ vào bộ nhớ ngẫu nhiên. Cách này nằm segfaults. –
Vì vậy, nếu tôi hợp pháp muốn một con trỏ đến một con trỏ, tôi nên sử dụng hai 'alloca' cuộc gọi và sau đó' poke' một con trỏ vào khác, phải không? – zmthy
có (hoặc sử dụng một số hình thức phân bổ khác). Việc sử dụng phổ biến nhất cho một con trỏ tới một con trỏ là con trỏ ra các giá trị, trong trường hợp đó hàm ràng buộc làm cho việc phân bổ và các mảng của chuỗi (nghĩ 'argv'). Th –