2013-08-13 36 views
6

Đoạn mã sau nằm trong một thiết bị sẽ phát hành một thiết bịId (LXdeviceInfo) khi được liệt kê thông qua một kết nối ổ cắm IrDA. Điều này chỉ quan trọng để giải thích tại sao tôi muốn giữ các kiểu dữ liệu tương tự nhất có thể, nhưng có thể biên dịch bằng cách sử dụng ansi CCó cách nào để sửa đổi khối cấu trúc C++ cấu trúc này để làm việc trong thẳng C

Với #includes of windows.h và af_irda.h, mã sau đây biên dịch không lỗi trong trình biên dịch C++, nhưng ngắt trong trình biên dịch C ngay dưới cấu trúc gán (xem L ERI ở đây). Lý tưởng nhất là tôi muốn khởi tạo thành viên cấu trúc 'ID' thành một mảng ký tự trong khi vẫn giữ nó giống như trong mã ban đầu để tôi có thể kiểm tra giá trị của LXdeviceInfo giống như nó sẽ xuất hiện khi truy vấn nó gọi đến thiết bị từ kết nối ổ cắm PC.

Có cách nào để sửa đổi khối gán này để hoạt động ở chế độ C thẳng không?

#include <windows.h> 
#include <af_irda.h> 

#define IR_HINT_COMPUTER 0x04 
#define IR_HINT_EXT  0x80 
#define IR_HINT_OBEX  0x20 
#define IR_HINT_IRCOMM 0x04 
#define IR_CHAR_ASCII  0 
#define PROD_FAMILY_NAME ("product name goes here") 

#define uint8_t unsigned char 

const struct { 
    uint8_t hint1; 
    uint8_t hint2; 
    uint8_t charset; 
    uint8_t ID[sizeof(PROD_FAMILY_NAME)]; 
} devInfoStorage = 
{ 
    IR_HINT_COMPUTER | IR_HINT_EXT, // hint1 
    IR_HINT_OBEX | IR_HINT_IRCOMM, // hint2 
    IR_CHAR_ASCII,     // charset 
    PROD_FAMILY_NAME     // Prod ID string 
}; // ERROR here: Innvalid initialization type: found 'pointer to char' expected 'unsigned char' 

const uint8_t *LXdeviceInfo = (uint8_t *) &devInfoStorage; 

/* The size of the device info */ 
const uint8_t LXdeviceInfoLen = sizeof(devInfoStorage); 



void main(void) 
{ 

    #define DEVICE_LIST_LEN 10 

    unsigned char DevListBuff[sizeof (DEVICELIST) - 
           sizeof (IRDA_DEVICE_INFO) + 
           (sizeof (IRDA_DEVICE_INFO) * DEVICE_LIST_LEN)]; 

    int DevListLen = sizeof (DevListBuff); 
    PDEVICELIST pDevList; 

    pDevList = (PDEVICELIST) & DevListBuff; 
     //code continues. 

} 
+2

Thử xóa dấu ngoặc đơn khỏi PROD_FAMILY_NAME. –

+2

Theo như tôi có thể nói rằng cần phải hợp lệ C cũng. Có thể dấu ngoặc đơn xung quanh chuỗi rối tung lên? Hoặc có lẽ việc gán mảng không được thực hiện bởi vì một unsigned char và char không hoàn toàn phù hợp. –

+0

@ryyker những gì thay thế những định nghĩa với 'const' và' typedef' tương đương của họ? – greatwolf

Trả lời

11

Xóa dấu ngoặc đơn quanh chuỗi chữ. Các dấu ngoặc đơn làm cho macro mở rộng thành một biểu thức sẽ phân rã thành một kiểu con trỏ, mà làm cho nó không biên dịch trong trình biên dịch C của bạn. Không thể sử dụng loại con trỏ để khởi tạo một mảng. Không có dấu ngoặc đơn, chuỗi ký tự được sử dụng để khởi tạo mảng.

#define PROD_FAMILY_NAME "product name goes here" 

Các trạng thái tiêu chuẩn C mà một biểu thức trong ngoặc mất vào loại tương tự như khái niệm unparenthesized, C.99 § 6.5.1 ¶ 5:

Một biểu thức trong ngoặc đơn là một biểu thức chính. Loại và giá trị của nó giống hệt với biểu thức không được biểu thị. Nó là một giá trị, một hàm thiết kế hàm, hoặc một biểu thức void nếu biểu thức chưa được biểu thị tương ứng, một giá trị, một hàm thiết kế hàm, hoặc một biểu thức void.

Tuy nhiên, trong khi chuỗi ký tự là một biểu thức, thì trò chuyện không đúng. Cụ thể, một chuỗi ký tự không phải là một loại, mà là một thực thể được xác định. Việc khởi của mảng làm cho một phụ cấp cụ thể cho một chuỗi chữ, C.99 § 6.7.8 ¶ 14:

Một mảng của kiểu nhân vật có thể được khởi tạo bởi một chuỗi ký tự chữ, tùy kèm theo trong dấu ngoặc .

Các initializers phép khác cho một mảng được mô tả trong C.99 § 6.7.8 ¶ 16:

Nếu không, khởi tạo cho một đối tượng mà có tổng hoặc công đoàn loại được một cú đúp kèm danh sách các bộ khởi tạo cho các phần tử hoặc các thành viên được đặt tên.

Biểu thức được lồng tiếng không phải là chuỗi ký tự, cũng không phải là danh sách cặp ngoặc đơn kèm theo.

+0

Cảm ơn - điều đó đã làm được! – ryyker

+3

Trên thực tế, trông giống như một lỗi trong trình biên dịch C - dấu ngoặc đơn là hoàn toàn hợp pháp trong một trình khởi tạo, do đó không nên buộc trình biên dịch xử lý nó như là một biểu thức. Để so sánh, nó hoạt động tốt với gcc (mingw) –

+0

@ChrisDodd: Cảm ơn, lưu ý. – jxh

0

Như PROD_FAMILY_NAME là một (không đổi) chuỗi, trình biên dịch hy vọng ID được khai báo là một cái gì đó giống như uint8_t *ID; như dây thường được biểu diễn dưới dạng con trỏ đến các nhân vật trong bộ nhớ trong C. Xem ví dụ của tôi ở đây: http://ideone.com/m5ZZl0

Để làm điều này với một mảng ký tự như bạn có, bạn cần phải làm một strcpy hoặc memcpy từ tên họ sản phẩm vào mảng byte ID của bạn vì C không hỗ trợ gán mảng trực tiếp theo như tôi biết. Nếu tên sản phẩm sẽ là một biến nhưng sẽ không thay đổi và sẽ không nằm ngoài phạm vi, tôi khuyên bạn nên sử dụng uint8_t* -typed ID, nhưng nếu bạn cần một bản sao của tên và không muốn tự động cấp phát bộ nhớ bạn có thể muốn gắn bó với một mảng (nhưng lưu ý rằng các phiên bản cũ của tiêu chuẩn C không hỗ trợ các mảng không có độ dài tĩnh, hoặc [mặc dù có nhiều cách để làm việc đó với một mảng có độ dài thay đổi tại kết thúc struct, nhưng bạn thường xuyên phải tiếp tục theo dõi những kích thước struct bằng tay trong trường hợp như sizeof() sẽ trở lại 0 cho mảng đó;. những thứ như strlen() vẫn sẽ làm việc tốt, mặc dù)


có vẻ tôi quên rằng, trong khi gán mảng không được phép, một cái gì đó như char array[] = "literal string"; vẫn còn. Vì vậy, trên của tôi là một chút vô nghĩa, nhưng tôi nghĩ rằng các cấu trúc kích thước động không phải là tất cả những gì tốt nếu bạn muốn có một mảng các cấu trúc như vậy, trong trường hợp đó phương pháp char* có thể một ý tưởng tốt hơn (ngay cả khi nó chỉ là một con trỏ đến một mảng ở nơi khác).

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