2011-07-20 52 views
6

Tôi là không hỏi về WHEN để liên kết các ngôn ngữ lập trình khác nhau.Cách kết hợp các ngôn ngữ lập trình khác nhau

Đây là một câu hỏi chung nhưng tôi cá nhân làm việc trên Linux.

Điều tôi muốn hiểu là quá trình theo đó các ngôn ngữ lập trình khác nhau có thể được kết hợp , tôi đã tìm thấy một bài viết hay về kết hợp C/C++/Fortran: http://www-h.eng.cam.ac.uk/help/tpl/languages/mixinglanguages.html.

Từ những gì tôi hiểu được hầu hết các trình biên dịch thực hiện hai giai đoạn: (? Có thể là tên hàm)

  1. Dịch các file ngôn ngữ vào các tập tin đối tượng có chứa mã máy nhưng vẫn chứa một số biểu tượng

  2. Linking các đối tượng tập tin với nhau, chỉ ở giai đoạn này Linker kiểm tra xem các hàm trong các tệp đối tượng có thể gọi được không.

Tôi nghĩ rằng vấn đề với cách kết hợp ngôn ngữ khác nhau là tên mangling có nghĩa rằng tên của các chức năng được thay đổi khi chúng được chuyển thành mã đối tượng.

Các câu hỏi là:

  1. Có thể bạn không bằng cách nào đó khám phá ra tên hàm đọc sai trước và so với chỉ định cho họ một cách rõ ràng bằng ngôn ngữ lập trình hay tốt hơn hết, không phải là có một phần mềm mà đã thực hiện điều đó?

  2. Tôi không hiểu hoàn toàn cách thư viện động được liên kết nhưng có thể các ngôn ngữ khác nhau tương tác bằng cùng một phương thức mà chương trình tương tác với thư viện động?

p.s Mục đích chính là gọi các hàm được viết bằng ngôn ngữ khác.

Trả lời

6

Vấn đề với việc liên kết các tệp đối tượng khác nhau với nhau thường đi xuống quy ước gọi điện của chương trình con. Về cơ bản, khi bạn thực hiện cuộc gọi đến một thường trình nằm trong một tệp đối tượng khác, trình biên dịch của bạn sẽ phải biết những gì mà tệp đối tượng khác sẽ đặt tên cho nội bộ của nó, cách truyền tất cả các tham số của nó và (nếu có) thiết lập và mã dọn dẹp thói quen sẽ yêu cầu. Tất cả các công cụ này thường được nhóm lại với nhau dưới tiêu đề của calling convention s.

Mỗi trình biên dịch có các quy ước gọi riêng mà nó thích sử dụng cho các chương trình con. Lưu ý tôi đã nói "trình biên dịch", không phải ngôn ngữ. Quy ước gọi C trong Linux khác với quy ước gọi C trên Windows.

Vì vậy, khi bạn trộn ngôn ngữ, bạn cần một số cách để thông báo cho trình biên dịch về cách gọi hoặc chương trình con được gọi để sử dụng quy ước gọi của ngôn ngữ khác. Quy ước của C là một quy tắc phổ biến để sử dụng như một loại "lingua franca", giống như mọi nền tảng đều có trình biên dịch C. Tuy nhiên một số nền tảng (ví dụ: Windows) có nhiều quy ước gọi điện phổ biến.

Vì vậy, bây giờ chúng ta đặt câu hỏi bạn hỏi trong các ý kiến:

Có một cách phổ biến để "nói với trình biên dịch sử dụng quy ước gọi ngôn ngữ khác"?

Và câu trả lời là "Không, không thực sự". Một số ngôn ngữ đã xác định cách sử dụng các quy ước gọi điện của ngôn ngữ khác cụ thể. Ví dụ, C++ cho phép bạn đặt extern "C" trên các khai báo để báo cho trình biên dịch biết rằng (các) khai báo đang được sử dụng sử dụng quy ước gọi C. Ada hoàn thành điều tương tự với pragma Convention (X,...), trong đó X là tên quy ước. C, FortranCobol được xác định theo ngôn ngữ, nhưng bất kỳ điều gì khác được hỗ trợ (ví dụ: Windows 'Stdcall) là việc triển khai được xác định. Tuy nhiên, nếu bạn có một cặp ngôn ngữ mà người viết trình biên dịch không bao giờ nghĩ đến nhau, thì bạn không có lựa chọn nào khác ngoài việc yêu cầu cả hai sử dụng một số quy ước thứ ba mà cả hai đều biết (thường là của C). Ví dụ: để có được tiêu chuẩn C++ và Ada để tương thích, bạn sẽ có mã máy chủ xuất các thường trình của nó bằng cách sử dụng quy ước C và cho mã khách biết rằng các thói quen đang gọi đang sử dụng quy ước C.

+0

Thanx rất nhiều cho câu trả lời, có cách phổ biến để "yêu cầu trình biên dịch sử dụng quy ước gọi của ngôn ngữ khác không "? – fiftyeight

+0

Đây là một câu trả lời hay, để làm rõ, tôi sẽ biết ơn nếu bạn có thể cho tôi biết điều sau đây là chính xác: Chỉ có Công ước ABI/Gọi là bạn có thể liên kết với nhau các đối tượng khác nhau không, nếu tôi muốn có -ngôn ngữ ngôn ngữ như Perl hoặc PHP (được viết bằng C) có thể gọi hàm của tôi miễn là hàm sử dụng C ABI, nó sẽ hoạt động. Tôi chỉ cần thêm đối tượng được chia sẻ vào tệp cấu hình (như php.ini) hoặc liên kết nó theo một cách khác. – fiftyeight

+1

@fiftyeight, cho Perl, hãy xem ['Inline :: C'] (http://search.cpan.org/~sisyphus/Inline-0.48/C/C.pod). Miễn là bạn sử dụng C ABI, sẽ có cách này hay cách khác để làm cho nó hoạt động cho một ngôn ngữ kịch bản nhất định trong hầu hết các trường hợp. Các cách để làm cho nó hoạt động sẽ phụ thuộc vào các chi tiết của tình huống. Nhưng lưu ý rằng hầu hết các ngôn ngữ kịch bản được viết bằng C. Đối với những ngôn ngữ được triển khai trên JVM, bạn sẽ phải sử dụng các cơ sở của JVM để tương thích mã gốc (JNI và whatnot). – Lumi

0

"Chuẩn" là sử dụng các tên không bị cắt xén khi kết hợp các chương trình từ các ngôn ngữ khác nhau. Tên mangling có thể được tắt cho các ký hiệu cụ thể trong C++ bằng cách khai báo chúng với extern "C". C không mangle tên.

0

Tất cả các tệp thực thi thư viện có chứa một số loại giao diện. Nếu họ không làm, không có phần mềm nào có thể làm việc với họ. Nó có nhiều khả năng phương pháp nội bộ được thay đổi để có hiệu quả hơn. Ngoài ra, nhiều ngôn ngữ cho phép bạn tắt "mangling" ở cấp trình biên dịch.

Liên kết, như là một lời giải thích đơn giản (tôi có thể sẽ được dinked cho điều này?), Là đóng gói vào một tập tin duy nhất. Các lớp giữ lại cùng một giao diện như các thư viện không liên kết, ít nhất là từ một quan điểm lập trình bên ngoài.

1

Các ngôn ngữ khác nhau chắc chắn có thể sử dụng cùng một thư viện. Trên Windows Visual Basic cũ, nó khá phổ biến để tự động tải các hàm Windows API, ví dụ.

Tất cả những gì bạn cần cho liên kết liên ngôn ngữ là thỏa thuận về các quy ước gọi điện của hàm, cùng với kiến ​​thức về tên hàm.Trước đây phải được thực hiện bằng cách tra cứu tài liệu; sau này phải được tìm kiếm trong trình biên dịch đã tạo ra các đối tượng hoặc thư viện. Ví dụ: gcc sẽ biên dịch C mà không có tên mangling, vì vậy bạn có thể tham chiếu trực tiếp đến tên hàm khi chúng ở trong nguồn C của bạn, trong khi g++ sẽ biên dịch mã C++ với tên bị xé và tốt nhất bạn nên để lộ hàm C qua khai báo extern "C".

Về cơ bản, miễn là các đối tượng hoặc thư viện của bạn chỉ trưng bày C ABI, cần có sự hỗ trợ rộng rãi để gắn kết với các ngôn ngữ khác. Sẽ khó hơn rất nhiều nếu bạn muốn sử dụng một thư viện C++ nguyên gốc, ví dụ, vì trong trường hợp đó, các ngoại ngữ của bạn phải thực hiện đúng C++ ABI. Nó tương tự như xuất khẩu mã từ, nói, Fortran, nhưng tôi tin rằng có thể được thực hiện để chỉ sử dụng C ABI.

+0

Tôi không hoàn toàn hiểu phần cuối, ý của bạn là gì bởi "đối tượng hoặc thư viện của bạn chỉ trưng bày C ABI" – fiftyeight

+0

Vâng, thư viện của bạn có thể sử dụng tất cả những thứ nội bộ khác nhau (như nội dung C++) không thể dễ dàng có ý nghĩa bên ngoài, nhưng miễn là các chức năng mà bạn muốn phơi bày với những người khác tuân theo C ABI, các chương trình khác có thể liên kết chúng một cách linh hoạt. –

+0

Làm cách nào để biết trình biên dịch/ngôn ngữ tôi sử dụng có tương thích với C ABI hay không, có cách nào để biết điều này không? – fiftyeight

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