2013-03-16 30 views

Trả lời

4

Bạn sẽ cần phải "quấn" C++ giao diện của bạn với chức năng C thường xuyên mà phải mất một tham số để chỉ ra những gì đối tượng họ sẽ được gọi. Ví dụ, nếu bạn có trong C++

class A 
{ 
    // .. boilerplate stuff... 
    int SomeMethod(int n, float f); 
}; 

Sau đó, cùng với nó, bạn có thể khai báo một chức năng như

extern "C" int A_SomeMethod(void* Obj, int n, float f) 
{ 
    return(((A*)Obj)->SomeMethod(n, f)); 
} 

Nếu bạn không thoải mái với những đúc của void *, bạn có thể triển khai một số loại bản đồ từ một xử lý mờ đến A*. Nhưng ý chính là bạn sẽ cần phải giữ một số xử lý/con trỏ tới đối tượng mà phương thức sẽ được gọi. Để có được con trỏ/xử lý bạn sẽ cần phải quấn phân bổ đến:

extern "C" void* A_Instantiate() 
{ 
    return new A; 
} 

C++ file nên được biên dịch riêng rẽ cùng với các tập tin với các chức năng trên. Một bao gồm riêng biệt cho việc biên dịch C nên bao gồm các khai báo của tất cả các hàm ở trên.

CHỈNH SỬA: Các lưu ý và ý kiến ​​dưới đây rất quan trọng; để trả lời câu hỏi, "Có, có thể gọi C++ từ C", và đây là một cách tiếp cận. Nó không phải là một cách tiếp cận hoàn chỉnh vì không thực sự là một cách cơ học để làm điều đó, nhưng đó là một sự khởi đầu. Ngoài ra, đừng quên tạo một cuộc gọi khác cho delete, v.v.

+0

Cảm ơn wilsonmichaelpatrick, nhưng những gì về việc sử dụng * Biên dịch * C + + mã trong chương trình C của tôi ?! – S0H31L

+0

'A' được sử dụng khi đúc' Obj' ?! Nó là một loại được xác định trước hay cấu trúc ?! – S0H31L

+0

'A' là loại lớp C++. Ngay cả với mã C++ đã biên dịch, phương pháp này cũng có tác dụng. Tất cả những gì bạn cần làm là định nghĩa các phương thức "C" bên ngoài dọc theo các dòng mà tôi đã mô tả ở trên và sử dụng các phương thức đó để gọi đến mã C++ của bạn. Bản thân mã C++ không được thay đổi. – wilsonmichaelpatrick

0

có, bạn cần phải xác định nó như

extern "C"

cách này nó sẽ làm cho các chức năng để có "C" liên kết, sau đó mã C có thể gọi chức năng của bạn chỉ như thể nó ở C. Tên chức năng này sẽ không bị xáo trộn vì C không hỗ trợ quá tải.

đây cho tôi trích dẫn @Faisal Vali:

  • extern "C" là một mối liên kết đặc điểm kỹ thuật
  • Mỗi trình biên dịch là cần để cung cấp "C" liên kết
  • một đặc tả mối liên hệ sẽ xảy ra chỉ trong phạm vi không gian tên
  • tất cả các loại chức năng, tên hàm và tên biến có liên kết ngôn ngữ
  • hai loại chức năng với biệt hiệu riêng biệt mối liên kết ge nhiều loại khác nhau ngay cả khi cách khác giống hệt
  • liên kết thông số kỹ thuật tổ, một bên trong xác định mối liên hệ chính thức
  • extern "C" được bỏ qua cho các thành viên lớp
  • nhiều nhất một chức năng với một tên cụ thể có thể có "C" liên kết (không phân biệt không gian tên)
  • extern "C" buộc một chức năng để có mối liên hệ bên ngoài (không thể làm cho nó tĩnh)
  • Mối liên hệ từ C++ với các đối tượng quy định tại các ngôn ngữ khác và các đối tượng quy định tại C++ từ các ngôn ngữ khác là implementation- được xác định và phụ thuộc vào ngôn ngữ. Duy nhất mà các chiến lược bố trí đối tượng của hai triển khai ngôn ngữ đủ tương tự như mối liên hệ như vậy có thể đạt được

see Faisal Vali answer here

+0

Điều này sẽ chỉ hoạt động đối với các chức năng tương thích với C (phiên bản _one_ của các hàm bị quá tải, nếu quá tải trong điều này thậm chí còn được xử lý; không có tham chiếu, chắc chắn không phải chức năng thành viên, không cho lớp hoặc đối tượng; và với nhiều hạn chế). Đây không phải là ý định của tiêu chuẩn, nó là để có thể gọi vào C từ C++, không phải là cách khác xung quanh; vì vậy nó thậm chí có thể không được công cụ C++/C của bạn không cho phép. – vonbrand

0

Q: Tôi có thể truy cập vào mã C của tôi từ C++ hoặc ngược lại?

A: Có.

1) Điều quan trọng là sử dụng extern "C" { ...} trong tất cả các tiêu đề của bạn để biểu thị các chức năng và dữ liệu C-chỉ, như thế này:

http://en.wikipedia.org/wiki/Compatibility_of_C_and_C%2B%2B

/* Header file foo.h */ 
#ifdef __cplusplus /* If this is a C++ compiler, use C linkage */ 
extern "C" { 
#endif 

/* These functions get C linkage */ 
void foo(); 

struct bar { /* ... */ }; 

#ifdef __cplusplus /* If this is a C++ compiler, end C linkage */ 
} 
#endif 

2) Tình huống thông thường là C++ chính chương trình gọi các hàm và cấu trúc C và C++. Các cấu trúc và chức năng đều được khai báo trong các tiêu đề, và tất cả đều có "#ifdef __cplusplus/extern C".

3) Đây là một câu hỏi thường gặp tốt về trộn C và C++:

http://www.parashift.com/c++-faq/mixing-c-and-cpp.html

+2

Từ những gì tôi đọc: đây là một dự án trong C, mà đang cố gắng gọi một số mã C++, và bạn đang trả lời như thể nó là một chương trình C++ gọi hàm C. – qdii

+0

@ paulsm4: tnx cho câu trả lời của bạn, nhưng qdii là đúng :) – S0H31L

0

Trừ khi yêu cầu nghiêm ngặt, điều này chỉ dành cho những người đeo giả da nhuộm. Làm điều đó sẽ đòi hỏi sự chăm sóc cực kỳ trên cả hai mặt, và cũng có thể làm việc ngày hôm nay và phát nổ ngoạn mục với bản cập nhật trình biên dịch tiếp theo. C++ đòi hỏi rất nhiều thời gian chạy giúp đỡ, và nhận được rằng để làm việc đáng tin cậy từ C thường không được hỗ trợ. Bạn có thể gọi vào C từ C++, được hỗ trợ chính thức (và một phần của tiêu chuẩn, extern "C" và như vậy).

Có lẽ đặt cược tốt nhất là viết C của bạn trong tập hợp con được xử lý bởi C và C++ (điểm bắt đầu trên sự khác biệt tinh tế là this) và biên dịch với trình biên dịch C++. Hoặc vượt qua nó và quyết định ngôn ngữ nào bạn thích nhất.

+0

cảm ơn, về việc sử dụng mã C++ đã biên dịch trong chương trình C của tôi thì sao ?! P.S: Đó là * Yêu cầu nghiêm ngặt! *: S – S0H31L

+0

Biên dịch với trình biên dịch C++. Bất cứ điều gì khác là điên rồ. Lý do không sử dụng C++ là một số vấn đề liên quan đến ngôn ngữ (lập trình viên không biết ngôn ngữ, chống lại chính sách, được coi là quá kém hiệu quả, bất kỳ điều gì) hoặc do các yêu cầu thời gian chạy. Những cái đầu tiên có thể được giải quyết và sử dụng C++ thống nhất; chi phí thứ hai bạn sẽ phải trả với một chimaera anyway, ngoài các vấn đề phụ do hỗn hợp ngôn ngữ. – vonbrand

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