2012-04-24 26 views
9

Giả sử tệp tiêu đề sau tương ứng với, ví dụ: một thư viện được chia sẻ. Chức năng xuất khẩu mất một con trỏ đến một cấu trúc tùy chỉnh theo quy định tại tiêu đề này:Liên kết cấu trúc C và tính di động giữa các trình biên dịch

// lib.h 

typedef struct { 
    char c; 
    double d; 
    int i; 
} A; 

DLL_EXPORT void f(A* p); 

Nếu thư viện chia sẻ được xây dựng bằng một trình biên dịch và sau đó được sử dụng từ mã C được xây dựng với trình biên dịch khác nó có thể không làm việc vì một khác nhau liên kết bộ nhớ, như là Memory alignment in C-structs gợi ý. Vì vậy, có cách nào để làm cho định nghĩa cấu trúc của tôi di động trên các trình biên dịch khác nhau trên cùng một nền tảng?

Tôi quan tâm đặc biệt trong nền tảng Windows (dường như nó không có ABI được xác định rõ ràng), mặc dù bạn cũng tò mò muốn tìm hiểu về các nền tảng khác.

+3

Không, trừ khi ai đó đảm bảo với bạn điều đó. –

+3

Không trùng lặp. Ít nhất không phải của câu hỏi được chọn. Cái này có thể tự đứng vững. –

+1

Có bất kỳ câu hỏi nào có chứa từ "struct alignment" tự động trùng lặp với câu hỏi khác ngay cả khi nó không liên quan gì đến nó? .. –

Trả lời

11

TL; DR trong thực tế bạn nên ổn.

Tiêu chuẩn C không xác định điều này mà là một nền tảng ABI thường làm. Đó là, đối với một kiến ​​trúc CPU và hệ điều hành đã cho, có thể có một định nghĩa về cách C ánh xạ tới assembly cho phép các trình biên dịch khác nhau tương thích với nhau.

Căn chỉnh cấu trúc không phải là điều duy nhất mà nền tảng ABI phải xác định, bạn cũng có các quy ước gọi điện và các công cụ tương tự.

C++ làm cho nó thậm chí còn phức tạp hơn và ABI có để xác định vtables, trường hợp ngoại lệ, tên mangling vv

Trên Windows Tôi nghĩ rằng có nhiều C++ Abis tùy thuộc vào trình biên dịch nhưng C là chủ yếu tương thích trên các trình biên dịch. Tôi có thể sai, không phải chuyên gia Windows.

Một số liên kết:

Dù sao Điểm mấu chốt là bạn đang tìm kiếm sự bảo đảm của bạn trong nền tảng/trình biên dịch ABI spec, không phải chuẩn C.

+0

Cảm ơn những nỗ lực của bạn, mặc dù câu hỏi của tôi không liên quan đến C++ cả. Tôi biết về ABI, đó cũng là lý do tại sao tôi đánh dấu câu hỏi Windows cụ thể như tôi chưa bao giờ nghe nói về thông số kỹ thuật của ABI trên Windows. –

+0

@ 7vies: C cũng có ABI (nghĩ về các quy ước gọi điện khác nhau, cdecl, stdcall, fastcall). Nó chỉ là cho C các trình biên dịch khác nhau thường là như nhau (ít nhất là cho các quy ước gọi 'bình thường'), nếu không có lý do khác hơn để phù hợp với những gì hệ điều hành mong đợi cho các cuộc gọi hệ thống. Với C++ các trình biên dịch khác nhau thường * không * đồng ý trên cùng một API, đặc biệt là cho các tên bên ngoài. –

+0

@MichaelBurr, như một lưu ý phụ, wikipedia nói đây là các quy ước _x86_, chúng có được sử dụng trên các kiến ​​trúc khác không? Tôi nhận thức được các vấn đề C++, đó là lý do tại sao tôi hỏi làm thế nào để làm cho nó hoạt động trong C. Các quy ước gọi điện giúp xác định một giao diện di động, nhưng không giải quyết vấn đề của tôi với sự liên kết cấu trúc. –

1

Không chỉ là nó không được bảo đảm, nhưng ngay cả khi bạn sử dụng cùng trình biên dịch có thể có sự khác biệt do các trình biên dịch khác nhau được sử dụng trong bản dựng, hoặc nếu bạn sử dụng các phiên bản khác nhau của cùng một trình biên dịch và cùng một thiết bị chuyển mạch một trình biên dịch nhúng tôi đã làm việc trên).

Bạn cần đảm bảo cấu trúc được biểu diễn chính xác như nhau, sử dụng các công tắc, #pragmas, bất kể trình biên dịch nào cung cấp cho bạn.

Lời khuyên của tôi - để tránh xa điều này. Vượt qua các đối số của bạn trong hàm, không được bọc trong một cấu trúc.

Và ngay cả trong hình thức đơn giản này, nếu bạn đối phó với hai trình biên dịch, nó không phải là tầm thường. Bạn cần đảm bảo rằng một int lấy cùng một số byte, ví dụ. Cũng gọi conevntion - đối số thứ tự - từ trái sang phải hoặc từ phải sang trái - có thể khác nhau giữa trình biên dịch.

3

Cách duy nhất để biết chắc chắn là tham khảo tài liệu về các trình biên dịch được đề cập.Tuy nhiên, thường là trường hợp bố cục C struct (ngoại trừ, như bạn nói, đối với bitfield) được xác định bởi một mô tả ABI cho môi trường bạn đang sử dụng, và trình biên dịch C sẽ có xu hướng theo ABI gốc.

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