2011-02-08 39 views
5

Tôi có một tập tin lắp ráp (asm.S) cần một hằng số #define 'd trong một tập tin tiêu đề C (c_decls.h). Tệp tiêu đề chứa các khai báo hàm C ngoài số #define mà tôi muốn. Thật không may, gcc barfs khi cố gắng biên dịch tập tin lắp ráp. Ví dụ,#include tiêu đề có khai báo C trong tệp lắp ráp không có lỗi?

c_decls.h

#ifndef __c_decls_h__ 
#define __c_decls_h__ 

#define I_NEED_THIS 0xBEEF 
int foo(int bar); 

#endif 

asm.S

#include "c_decls.h" 

.globl main 
main: 
    pushl %ebp 
    movl %esp, %ebp 
    movl $I_NEED_THIS, %eax 
    leave 
    ret 

Output

> gcc -m32 asm.S
c_decls.h: Assembler messages:
c_decls.h:6: Error: junk '(int bar)' after expression
c_decls.h:6: Error: suffix or operands invalid for 'int'

Có cách nào để #include tệp tiêu đề C có chứa khai báo hàm trong tệp assembly? (Thay đổi tiêu đề hoặc di chuyển/xác định lại số #define không phải là một tùy chọn.)

+0

(Thay đổi tiêu đề hoặc di chuyển/xác định lại #define không phải là một tùy chọn.) Xem ing khi bạn đã loại bỏ các tùy chọn hợp lý nhất, tôi muốn nói rằng bạn đang ra khỏi may mắn. :-) – asveikau

+0

Xem xét rằng tiêu đề đang gọi hành vi không xác định (bằng cách sử dụng tên bắt đầu bằng dấu gạch dưới kép làm bảo vệ đa phần của nó), tôi nghĩ bạn nên xem xét lại yêu cầu không thay đổi nó. :-) –

Trả lời

10

Sử dụng tùy chọn -dM cho cpp để chỉ lấy #defines ra khỏi tệp tiêu đề của bạn và bao gồm tệp đó.

cpp -dM c_decls.h > bare_c_decls.h 

Bây giờ bao gồm bare_c_decls.h trong tệp .S của bạn. Và nếu bạn không thể thay đổi #include trong tệp .S, tạo các tệp tiêu đề trần trong một thư mục khác và đặt đường dẫn đó vào dòng lệnh trình biên dịch/trình biên dịch của bạn, trước mọi thứ khác.

Và cuối cùng, bạn có thể bọc tất cả trong một tệp makefile để các tệp tiêu đề "trần" của bạn được tạo tự động.

+1

Đơn giản '-dM' không hoạt động đối với tôi. Nó không trả lại gì cả. '-E -dM' dumps tất cả các định nghĩa, bao gồm cả một được định nghĩa trong một tiêu đề. Chỉ có sự bất tiện mà có hơn 700 định nghĩa trong danh sách. – user3124812

+0

Bạn đang sử dụng phiên bản cpp nào? (Lưu ý câu hỏi liên quan đến gcc) – payne

+0

Đó là GNU GCC, 'arm-no-eabi-g ++ (Công cụ GNU dành cho Bộ xử lý nhúng ARM) 4.9.3 20150529 (bản phát hành)' – user3124812

6

Đó là simle: Trong tập tin của bạn sử dụng .S

#define __ASSEMBLY__ 

Trong sử dụng tập tin .C của bạn

#undef __ASSEMBLY__ 

Sau đó trong file .h nơi điều kiện

 #ifdef __ASSEMBLY__ 
        // here declarations only for assembler 
     #else 
        // here only for C 
     #endif 
        // and here - defines suitable for both 
+0

Tiêu đề phải được bao gồm trong 'C' như bao gồm '#include my_defs.h', không phải 'ASM' như' .bao gồm my_defs.h'. Trong trường hợp cuối cùng '# ifdef',' # else', '# endif' sẽ bị bỏ qua bởi trình phân tích cú pháp asm. Chỉ cần vấp phải điều này ... – user3124812

+1

'gcc foo.S' đã được định nghĩa trước' __ASSEMBLER__' thành 1. Vì vậy, bạn chỉ có thể bảo vệ tất cả các công cụ C của bạn với '#ifndef __ASSEMBLER__' –

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