Bạn đề cập đến trong một chú thích mà bạn đang sử dụng void*
“bởi vì nó sẽ có thể lấy địa chỉ của bất cứ điều gì; Không chỉ là một chuỗi. ”
Vì vậy, người ta phải hỏi làm thế nào để con trỏ chung dịch sang Ada, đặc biệt theo cách tận dụng các tính năng nhập và đánh máy phụ. Tôi sẽ đệ trình rằng “bất cứ điều gì”, trong bối cảnh này, không thể được giải quyết một cách tổng quát; đó là để nói, nếu bạn muốn duy trì tính linh hoạt của cấu trúc, bạn phải hy sinh những lợi thế mà Ada cung cấp với hệ thống kiểu của nó. Hơn nữa, tôi trình bày như là, nó thường không thể sử dụng đáng tin cậy cho "bất cứ điều gì".
Tôi nói điều này bởi vì không có phương pháp xác định ngay cả chiều dài của “bất cứ thứ gì”. Nếu đó là một chuỗi thì chiều dài là từ địa chỉ được chỉ định, đếm liên tục, cho đến ký tự NUL đầu tiên (ASCII 0) . Tuy nhiên, không có phương pháp xác định độ dài nếu nó không phải là một chuỗi (làm thế nào chúng ta biết chiều dài/kích thước của mảng [1,2,3] hoặc OBJECT) ... và vì vậy chúng tôi không có phương pháp để xác định ngay cả chiều dài của “bất cứ điều gì.”
Xác định độ dài là yếu tố quan trọng trong việc viết mã ổn định/an toàn, bởi vì nếu bạn không mời tràn bộ đệm.
Nhưng, để lại mà đi, nếu bạn có thể cung cấp một số thông tin về dữ liệu, cho dù qua tham số hoặc thay đổi my_struct
, sau đó chúng ta có thể sử dụng thông tin đó để xây dựng một kiểu chuyển đổi tốt hơn. (Nói chung, bạn càng có nhiều thông tin về loại tốt hơn, vì sau đó bạn có thể kiểm tra tính hợp lệ của dữ liệu theo cách bạn không thể làm trước đó; hoặc tốt hơn, hãy kiểm tra trình biên dịch cho bạn.)
Type Data_Type is Array(Positive Range <>) of Interfaces.Unsigned_8;
For Data_Type'Component_Size Use 8;
Function Some_Data(Stream : not null access Ada.Streams.Root_Stream_Type'Class;
Length : In Positive) Return Data_Type is
begin
Return Result : Data_Type(1..Length) do
For Index in Result'Range loop
Interfaces.Unsigned_8'Read(Stream, Result(Index));
end Loop;
End Return;
end Some_Data;
Bạn có thể sử dụng phần trên để tạo một mảng gồm các số nguyên không dấu 8 bit có chứa dữ liệu từ luồng. Nó phác thảo những gì bạn phải làm trong trường hợp chung, mặc dù kể từ khi bạn đang làm việc với C-nhập khẩu những gì bạn có thể làm là sửa đổi nó một chút để a) có một biến Temp
mà là một mảng như Result
nhưng sử dụng For Temp'Address Use [...]
để phủ nó lên my_type.value và sau đó sử dụng vòng lặp for để sao chép nó.
Bạn nên xem gói «Interfaces.C.Strings', chứa một loại' chars_ptr'. Hàm C bạn nhập phải sử dụng kiểu chars_ptr thay vì dấu *. – oenone
Ngoài ra, hãy xem các giải pháp được đề xuất tại đây: http://en.wikibooks.org/wiki/Ada_Programming/Types/access#Where_is_void.2A.3F – oenone
Thành viên 'void *' thuộc loại là 'void *' vì nó nên có thể lấy địa chỉ của bất cứ điều gì; không chỉ là một chuỗi.Đó là lý do tại sao 'g ++' tạo ra thông số Ada cho nó và sử dụng' System.Address'. Tôi thấy kỹ thuật này hiện đang hoạt động. Có lẽ đó là âm thanh? – Anthony