2012-02-13 44 views
6

Cân nhắc tôi có Struct như sau:Địa chỉ của cấu trúc có giống với địa chỉ của thành viên đầu tiên không?

struct Bitmask 
{ 
    unsigned char payload_length: 7; 
    unsigned char mask: 1; 
    unsigned char opcode: 4; 
    unsigned char rsv3: 1; 
    unsigned char rsv2: 1; 
    unsigned char rsv1: 1; 
    unsigned char fin: 1; 
}; 

const char* payload = "Hello"; 
const size_t payload_length = strlen(payload); 

Bitmask* header = new Bitmask(); 
header->fin =1; 
header->rsv1 = 0; 
header->rsv2 = 0; 
header->rsv3 = 0; 
header->opcode = 1; 
header->mask = 0; 
header->payload_length = payload_length; 

iovec iov[2]; 
iov[0].iov_base = (char*)header; 
iov[0].iov_len = sizeof (header); 
iov[1].iov_base = (char *)payload; 
iov[1].iov_len = strlen(payload); 

ACE_DEBUG ((LM_DEBUG, 
      ACE_TEXT ("iov[0].length = %d\niov[1].length = %d\n"), 
      iov[0].iov_len, 
      iov[1].iov_len)); 

size_t bytes_xfered; 
client_stream_.sendv_n (iov, 2, 0, &bytes_xfered); 

cout << "Transfered " << bytes_xfered << " byte(s)" << std::endl; 

Tôi khởi tạo nó với các giá trị thích hợp. Cuối cùng, tôi muốn chuyển đổi cấu trúc thành char * để tôi có thể nối thêm tải trọng của tôi (đó là char * message) và gửi nó qua kết nối websocket.

Trả lời

14

Địa chỉ của cấu trúc giống với địa chỉ của thành viên đầu tiên?

Có, điều này thực sự được bắt buộc theo tiêu chuẩn C và C++. Từ tiêu chuẩn C:

6.7.2.1-13. Con trỏ đến đối tượng cấu trúc, được chuyển đổi phù hợp, trỏ đến thành viên ban đầu của nó

Kích thước của struct phải là hai byte. Bạn không nên chuyển đổi một con trỏ sang nó thành char*, mặc dù: thay vào đó, bạn nên sử dụng memcpy để sao chép Bitmask vào bộ đệm mà bạn gửi qua mạng.

EDIT Vì bạn sử dụng phân tán tập hợp I/O với iovec, bạn không cần phải cast Bitmask để bất cứ điều gì: iov_basevoid*, vì vậy bạn chỉ có thể thiết lập iov[0].iov_base = header;

Lưu ý: Đây chỉ hoạt động càng lâu như struct của bạn không chứa chức năng ảo, lớp cơ sở, v.v. (cảm ơn, Timo).

EDIT2

Để có được {0x81, 0x05} trong struct của bạn, bạn nên thay đổi thứ tự của các yếu tố cấu trúc như sau:

struct Bitmask { 
    unsigned char opcode: 4; 
    unsigned char rsv3: 1; 
    unsigned char rsv2: 1; 
    unsigned char rsv1: 1; 
    unsigned char fin: 1; 
    unsigned char payload_length: 7; 
    unsigned char mask: 1; 
} 
+7

Trong C++, điều này chỉ đúng đối với cấu trúc POD. – Timo

+0

Tôi có cần phải sao chép thành viên Bitmask theo thành viên hoặc theo dõi sẽ làm: tiêu đề char_ [2]; memcpy (header_, bitmask, 2); –

+0

@DarshanPuranik Tôi không nhận ra rằng bạn đang sử dụng I/O thu thập phân tán. Xem chỉnh sửa của tôi. – dasblinkenlight

1

Có và không.

Nói chung, điều này đúng (như dasblinkenlight giải thích), nhưng nó đặc biệt không giữ cho bitfields. Per C++ 11 9.6/3 "không có con trỏ tới bitfields" vì vậy chúng không có địa chỉ. Và rõ ràng, "Một con trỏ đến một đối tượng cấu trúc, được chuyển đổi phù hợp, trỏ đến thành viên ban đầu của nó" bị hỏng nếu không có "chuyển đổi phù hợp".

1

Địa chỉ của cấu trúc giống với địa chỉ của thành viên đầu tiên, với điều kiện sử dụng dàn diễn viên phù hợp. Với khai báo dưới đây của struct my_struct, nếu mục là loại struct

my_struct, sau đó (char *) item == & item.wp_cval.

struct my_struct {

char wp_cval; 
    short wp_font; 
    short wp_psize; 

} ar [ARSIZE];

Các vấn đề liên quan