Làm thế nào tôi có thể viết một tập hợp các hàm có thể được gọi từ (gần như) bất kỳ ngôn ngữ lập trình nào?


33

Tôi muốn tìm cách viết API có thể được truy cập từ bất kỳ ngôn ngữ lập trình nào khác thông qua các ràng buộc ngôn ngữ (hoặc một số khung công tác khác). có khả năng làm cái này không? Nếu vậy, ngôn ngữ lập trình nào sẽ phù hợp nhất để viết API "ngôn ngữ chéo"? Mục tiêu của tôi là tạo ra một tập hợp các hàm mà tôi có thể truy cập từ bất kỳ ngôn ngữ lập trình nào mà tôi đang làm việc, do đó tôi sẽ không cần phải viết lại toàn bộ API theo từng ngôn ngữ.


4
Nếu bạn chỉ muốn có thể nói "chúng tôi hỗ trợ MỌI THỨ" vì lý do tiếp thị, bạn có thể chỉ cần viết một DLL cấp thấp hoặc thư viện chia sẻ trong C. Nếu bạn muốn bất kỳ ai nói, Java, hãy sử dụng điều của bạn, bạn cung cấp giao diện Java tốt hơn.
mjfgates

1
Bạn nói "(gần như) bất kỳ", ngôn ngữ nào bạn sẽ loại trừ cho mục đích này? Hay đó là những gì quan trọng nhất với bạn?
funkybro

22
Dịch vụ web? Bạn có thể viết một số chức năng trong ví dụ php. Hầu như bất kỳ ngôn ngữ nào cũng có khả năng giao tiếp với các trang web, cung cấp đối số và đọc kết quả.
Pieter B

7
+1 'vì đó là một câu hỏi thú vị - nhưng câu hỏi của bạn sẽ được cải thiện bằng cách nói lý do tại sao bạn muốn làm điều này. Mục tiêu của bạn là gì?
TarkaDaal

@PieterB => trả lời.
Konrad Rudolph

Câu trả lời:


44

Bạn có một vài lựa chọn:

  1. Tạo giao diện HTTP, hầu hết mọi thứ đều có thể nói HTTP để bạn có được nhiều ngôn ngữ.

  2. Tạo một cái gì đó có thể được liên kết vào một thời gian chạy ngôn ngữ, điều này sẽ khá tốn thời gian vì bạn sẽ cần phải tìm cách kết nối nó với nhiều ngôn ngữ khác nhau.


Cụ thể bạn đang nghĩ đến loại giao diện HTTP nào?
Anderson Green

@AndersonGreen Không thành vấn đề (vì bất kỳ ngôn ngữ nào có thể mở ổ cắm mạng đều có thể nói HTTP), nhưng REST là một tiêu chuẩn giả hữu ích.
Phục hồi lại

7
REST + JSON sẽ là một giải pháp hợp lý
David Hayes

Tôi cũng đồng ý, sử dụng HTTP để giao tiếp cho phép khá nhiều ngôn ngữ ngoài kia tương tác với các chức năng của ứng dụng của bạn.
Chỉ Bolivian ở đây

30

Tôi nghĩ rằng C hoặc C ++ sẽ phù hợp nhất cho mục đích của bạn. Bạn có thể sử dụng SWIG (Trình bao bọc đơn giản và Trình tạo giao diện) để tạo các ràng buộc ngôn ngữ từ API C hoặc C ++ của bạn.

SWIG là một công cụ phát triển phần mềm kết nối các chương trình được viết bằng C và C ++ với nhiều ngôn ngữ lập trình cấp cao. SWIG được sử dụng với các loại ngôn ngữ đích khác nhau, bao gồm các ngôn ngữ script phổ biến như Perl, PHP, Python, Tcl và Ruby. Danh sách các ngôn ngữ được hỗ trợcũng bao gồm các ngôn ngữ không phải là tập lệnh như C #, Common Lisp (CLISP, Allegro CL, CFFI, UFFI), ngôn ngữ D, Go, Java bao gồm Android, Lua, Modula-3, OCAML, Octave và R. triển khai (Guile, MzScheme / Vợt, Gà) được hỗ trợ. SWIG được sử dụng phổ biến nhất để tạo các môi trường lập trình được biên dịch hoặc biên dịch ở cấp độ cao, giao diện người dùng và là một công cụ để thử nghiệm và tạo mẫu phần mềm C / C ++. SWIG thường được sử dụng để phân tích các giao diện C / C ++ và tạo ra "mã keo" cần thiết cho các ngôn ngữ đích ở trên để gọi vào mã C / C ++. SWIG cũng có thể xuất cây phân tích cú pháp của nó dưới dạng các biểu thức XML và Lisp. SWIG là phần mềm miễn phí và mã mà SWIG tạo ra tương thích với cả các dự án thương mại và phi thương mại ...


32
C ++ sẽ là một lựa chọn khủng khiếp. Có rất nhiều vấn đề với nó: sự phụ thuộc vào thư viện thời gian chạy, ABI không xác định (đặc biệt là xáo trộn), v.v ... Tạo các ràng buộc từ các tiêu đề C ++ là cực kỳ khó khăn. SWIG là một điều khá hạn chế. Xem tất cả các cơ sở hạ tầng quá phức tạp xung quanh, giả sử, các ràng buộc Python Qt.
SK-logic

14
@ SK-logic: Không thực sự. C cần một lib thời gian chạy giống như C ++. ABI có thể được điều khiển trong C ++ thông qua extern "C"nên nó tương thích với C ở bên ngoài. Do đó, bạn có những lợi thế bên trong của C ++ (thư viện, an toàn loại cao hơn) nhưng những lợi thế bên ngoài của C (tiêu chuẩn ABI thực tế)
MSalters

3
@ SK-logic ABI không xác định chỉ đơn giản là một vấn đề được giải quyết, xem SWIG, Boost.Python và một loạt các ràng buộc ngôn ngữ khác.
Konrad Rudolph

3
@MSalters đừng quên các trường hợp ngoại lệ và sự không làm việc chung của họ qua các ranh giới thư viện
sehe

3
-1 cho đề xuất C ++. C thì dễ, C ++ làm cho mọi thứ trở nên khó khăn.
Ernest Friedman-Hill

23

Có khá nhiều 2 cách:

  • API C. Thực tế từng có ngôn ngữ từng có sẽ tải một thư viện C và gọi các chức năng của nó. Làm thế nào bạn làm điều này phụ thuộc vào ngôn ngữ nguồn.
  • một cơ chế RPC của một số loại. Đây có thể là API REST chạy trên HTTP hoặc giao diện nhị phân chạy trên ổ cắm. Trừ khi bạn sử dụng cơ chế mẫu số chung thấp nhất (ví dụ: ổ cắm), bạn sẽ gặp rủi ro không có thói quen truy cập máy khách (ví dụ: một số ngôn ngữ không có ứng dụng khách SOAP phù hợp để gọi API được triển khai bằng SOAP hoặc có vấn đề về khả năng tương tác). Bám sát đơn giản nhất, giao diện HTTP / REST hoặc ổ cắm. Các socket có lợi thế là chúng không cần máy chủ HTTP để hiển thị giao diện cho các máy khách và có thể dễ dàng chạy trên cùng một máy chủ với máy khách có hiệu suất tốt hơn.

Công việc cần thiết cho thay đổi này tùy thuộc vào hệ thống được sử dụng, ví dụ: giao diện ổ cắm sẽ hoạt động, nhưng các thư viện phía máy khách có xu hướng ở mức thấp hơn so với thư viện http.

Bạn có thể thử tìm thư viện mạng hỗ trợ tất cả các ngôn ngữ bạn muốn sử dụng và triển khai API theo thư viện đó - ví dụ: sử dụng ZeroMQ mang lại cho bạn rất nhiều tính linh hoạt, vì vậy bạn sẽ viết API bằng giao diện ZeroMQ và sau đó, bất kỳ ngôn ngữ nào muốn gọi API của bạn phải sử dụng thư viện máy khách ZeroMQ để làm như vậy. Chọn một thư viện hỗ trợ nhiều ngôn ngữ và cho phép bạn xử lý cũng như giao tiếp ngoài quy trình để có hiệu suất tốt nhất.


Vậy tôi cần thực hiện những bước nào nếu tôi muốn viết API bằng nhiều ngôn ngữ? (Trong trường hợp của tôi, những ngôn ngữ đó sẽ là Javascript, C ++ và Java.)
Anderson Green

Tôi có nên viết 3 API RESTful riêng biệt cho mỗi ngôn ngữ không?
Anderson Green

Bạn viết một trình bao bọc riêng trong mỗi ngôn ngữ này xử lý việc tải và gọi C dll bên dưới. Hoặc viết nó bằng C ++ và sử dụng SWIG để làm điều này cho bạn. Nếu bạn đang sử dụng API REST, thì cũng áp dụng tương tự, hãy viết một API đơn và sau đó là 3 trình bao bọc, nhưng nếu bạn đang viết API REST thì mỗi ngôn ngữ sẽ có thể gọi API REST trực tiếp - đừng bận tâm với một bọc
gbjbaanb

Dll (thư viện được liên kết động) có thể tương thích với bất kỳ nền tảng nào ngoài Windows không? Tôi cần khả năng tương thích đa nền tảng ở đây.
Anderson Green

không, bạn cần biên dịch lại nó cho các nền tảng khác. Linux ví dụ sử dụng .so thay vì. Chỉ cần biên dịch lại là cần thiết, không có thay đổi mã (hoặc rất nhỏ).
gbjbaanb

12

Nếu hiệu suất và độ trễ cuộc gọi không phải là vấn đề, hãy xem xét việc cung cấp giao diện dòng lệnh toàn diện (có thể, sử dụng ngôn ngữ kịch bản trên đầu trang). ImageMagick có thể là một ví dụ điển hình về "API" như vậy. Một ví dụ điển hình khác là bộ công cụ Tk.


Ngôn ngữ kịch bản và / hoặc ngôn ngữ lập trình nào bạn muốn giới thiệu cho mục đích tạo giao diện chức năng nước ngoài dòng lệnh? Ngoài ra, bạn đã tìm thấy bất kỳ ví dụ cụ thể của các giao diện như vậy?
Anderson Green

@AndersonGreen, bất kỳ ngôn ngữ nào có siêu lập trình tốt đều được chấp nhận cho mục đích như vậy. Ví dụ, Scheme, MetaLua, nhiều Lisps có thể nhúng khác, Tcl. Bạn có thể dễ dàng thực hiện ngôn ngữ lệnh của riêng bạn là tốt. Nhiều hệ thống CAD / CAE vận hành theo cách này. Một Tk đã được đề cập là một ví dụ điển hình khác.
SK-logic

Để sử dụng giao diện dòng lệnh theo cách này, bạn sẽ nhận được đầu ra giao diện điều khiển cho một lệnh cụ thể (chẳng hạn như whoamitrên Ubuntu để lấy tên người dùng), hoặc bạn có ý định gì khác không?
Anderson Green

@AndersonGreen, stdin đường ống và thiết bị xuất chuẩn nên có đủ trong hầu hết các trường hợp.
SK-logic

5

Theo API, chính xác ý bạn là gì?

Trên nhiều nền tảng, bạn có thể liên kết đến một DLL hoặc cấu trúc tương tự, nhưng liệu có phải được biên dịch lại cho một mục tiêu riêng cụ thể (Intel / ARM) hoặc endianness vẫn đủ điều kiện không? Một giao diện nhị phân cụ thể vẫn có thể gặp khó khăn với một số ngôn ngữ nhất định do các vấn đề hoặc cấu trúc kiểu dữ liệu (con trỏ cố gắng được trả về ngôn ngữ không hỗ trợ chúng tốt), vì vậy bạn cũng phải xem xét việc thiết kế API để không để loại trừ một số ngôn ngữ hoặc sử dụng nó từ các ngôn ngữ đó cồng kềnh.

Một cái gì đó di động như C và giao diện dựa trên các điểm cuối nhị phân trong DLL có thể tốt và thường có thể gọi được trên hầu hết các nền tảng và từ hầu hết các ngôn ngữ, nhưng nó có thể cần được biên dịch khác nhau và / hoặc được cung cấp theo các hương vị khác nhau hoặc được liên kết với các thư viện tĩnh khác nhau.

Đối với tôi, dường như sự lựa chọn ngôn ngữ bạn viết thư viện hoặc dịch vụ của bạn hoặc bất cứ điều gì, theo định nghĩa, không phải là nội tại cho câu hỏi cho đến khi bạn cung cấp thêm về nền tảng / dịch vụ mà API trưng ra. Nếu bạn có thể giả sử ngăn xếp mạng có sẵn và hiệu suất mức gọi hàm được liên kết trực tiếp không phải là một yêu cầu, API có thể dễ dàng dựa trên HTTP với một số loại shim cho ngôn ngữ máy khách để làm cho các yêu cầu được minh bạch.

Tôi nghĩ nói chung câu hỏi này quá rộng để có ích trong thế giới thực, bởi vì bạn chưa đưa ra dấu hiệu nào về loại API nào có thể phù hợp với loại dịch vụ đang được cung cấp.


2

Để thêm vào các câu trả lời trên có đề xuất sử dụng cơ chế RPC. Bạn có thể sử dụng Apache Thrift. ( Http://thrift.apache.org/ ). Nó về cơ bản là một khung RPC.

Theo wiki tiết kiệm:

Khung phần mềm Apache Thrift, để phát triển dịch vụ đa ngôn ngữ có thể mở rộng, kết hợp một ngăn xếp phần mềm với công cụ tạo mã để xây dựng các dịch vụ hoạt động hiệu quả và liền mạch giữa C ++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C #, Ca cao, JavaScript, Node.js, Smalltalk, OCaml và Delphi và các ngôn ngữ khác


Làm thế nào các cuộc gọi chức năng nước ngoài có thể được thực hiện bằng cách sử dụng Apache Thrift?
Anderson Green

0

Có bất kỳ ngôn ngữ nào viết ra một tệp văn bản có chức năng gọi các thông số để truyền vào. Có ứng dụng "Tôi kết hợp với bất kỳ ai" đang xem một thư mục và một khi nó thấy một quá trình - call.txt sẽ hoạt động. Không có máy chủ hoặc giao thức mạng; ngay cả một phương pháp ngôn ngữ phi máy tính cũng có thể khởi tạo các chức năng. Thậm chí một người chỉ có thể tạo tệp văn bản.

Nội dung có thể trông như:

Call-method:  fdisk()
Params:  (string) "/root", (string) "write-back-file-expected.txt"

;) bạn có thể đợi mãi để nhận được câu trả lời. Bạn chỉ cần đẩy một vài byte sang quy trình khác, nhưng tôi chắc chắn đó không phải là toàn bộ thông số kỹ thuật.


Có vẻ quá phức tạp khi bạn chỉ có thể có giao diện dòng lệnh + stdin / stdout.
Phục hồi lại

1
Cuộc gọi thậm chí tốt hơn có thể ++ 1 đó, Brendan. Tôi chưa bao giờ thấy nó hoạt động nhưng đã có lúc người ta đục lỗ trên thẻ để chuyển các byte xung quanh.
Pareshkumar

4
Đây là một câu trả lời đùa, phải không? Chúng tôi không làm điều đó ở đây.
Ernest Friedman-Hill

Chà, phần fdisk và / root là một trò đùa, nhưng tôi đã tham gia với tư cách là một nền tảng r & d (nhà phát triển và phân tích) trong hơn 5 năm để tạo ra một sản phẩm nền tảng tạo ra sản phẩm tốt trong 10 triệu đô la. Nó tạo ra hàng triệu mục vật lý có thể chuyển đổi (không phải pdf và email) cho khách hàng (với việc xử lý Tệp có phạm vi hàng trăm MB cho mỗi mục) bằng cách sử dụng loại phương pháp REST này. Chúng tôi đã có hệ thống triolgy chính - SAP-MS Office-PLC Drivewrs-PDF Workflow tất cả đều kết hợp với nhau và hoạt động tốt với các tệp văn bản UTF-8 cũ đơn giản và một zip có trong một zip có - trong một zip, và không có phí bs HTTP.
Pareshkumar

Tôi có thể hỏi một câu được không? Tại sao không ai nghĩ rằng JSON là một trò đùa? Làm thế nào là những gì tôi đề nghị bất kỳ khác nhau? Chúng tôi đã / có thể đã sử dụng json nhưng nó không xuất hiện vào năm 2003. XML quá béo, nhưng hồi đó, đó là hương vị của tháng không phải là linh hồn đơn giản và đơn giản nhất.
Pareshkumar

0

OpenGL là một ví dụ điển hình về những gì bạn mô tả - đó là một API được viết bằng C, được thiết kế theo cách dễ dàng để viết các ràng buộc cho các ngôn ngữ khác

  1. Thư viện C có thể được gọi từ hầu hết các ngôn ngữ lập trình (thường là các tiện ích mở rộng được biên dịch hoặc những thứ như ctypesthư viện của PyPy, v.v.)

  2. Tất cả các hàm lấy các kiểu dữ liệu đơn giản làm đối số (boolean, số nguyên, dấu phẩy động, hằng số, mảng), vì các hàm lấy con trỏ có thể khó xử khi dịch sang một số ngôn ngữ

  3. Có kiểu dữ liệu số của riêng nó, xác định độ chính xác và chữ ký (trong khi int floatvv có thể khác nhau)

API kết quả không nhất thiết phải là API C dễ sử dụng nhất mà bạn có thể viết nếu chỉ nhắm mục tiêu người dùng C. Tuy nhiên, điều đó có nghĩa là các chức năng có thể được tiếp xúc gần như trực tiếp với ngôn ngữ khác (ví dụ: tài liệu PyOpenGL liệt kê các điểm khác biệt, hầu hết trong số đó là khá tối thiểu)

Trên đầu API dài dòng này, bạn có thể viết thêm các trình bao bọc "thân thiện với nhà phát triển" xung quanh điều này (khung trò chơi và như vậy)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.