Khi nào chúng ta nên sử dụng các tệp nhị phân nhúng nhúng của Google, thay vì các khung được liên kết với nhau trong Xcode?


140

Có một câu hỏi hay về sự khác biệt giữa hai tùy chọn này như được mô tả trong Liên kết nhị phân với các thư viện VS Embed Frameworks .

Có vẻ như chúng ta có các tùy chọn để sử dụng cả hai, chỉ cần tự hỏi trường hợp nào chúng ta nên sử dụng nhị phân nhúng tốt hơn, hoặc thay vì khung được liên kết?

Bất kỳ ví dụ vững chắc để giải quyết điều này rõ ràng hơn? Cảm ơn


Câu trả lời:


239

Câu hỏi bạn đã liên kết tham chiếu chức năng "Liên kết nhị phân với thư viện", hơi khác so với nhị phân nhúng.

"Liên kết nhị phân với thư viện" có nghĩa là những gì bạn mong đợi liên quan đến liên kết: Bất kể nhị phân là thư viện tĩnh, thư viện động hay khung, nó sẽ được liên kết với mã đối tượng của bạn tại thời điểm liên kết sau khi biên dịch.

Khi bạn nghĩ về liên kết với một thư viện tĩnh, điều xảy ra khá rõ ràng: trình liên kết sao chép mã từ thư viện (ví dụ libFoo.a) vào nhị phân đầu ra của bạn. Tệp đầu ra của bạn tăng kích thước nhưng không cần giải quyết bất kỳ phụ thuộc bên ngoài nào trong thời gian chạy. Mọi thứ chương trình của bạn cần chạy (đối với thư viện tĩnh) đều có mặt sau khi được xây dựng.

Với thư viện động (.dylib hoặc khung do hệ thống cung cấp), kỳ vọng là thư viện mà bạn đang liên kết sẽ xuất hiện ở đâu đó trong đường dẫn trình tải thư viện động của hệ thống khi bạn chạy chương trình. Bằng cách này, bạn không cần phải sao chép tất cả các thư viện bên ngoài của bên thứ ba vào tệp nhị phân của mình và tất cả các chương trình khác nhau trên máy tính cũng liên kết với thư viện đó sẽ có thể tìm thấy nó, giúp tiết kiệm không gian đĩa tối thiểu, nhưng cũng không gian bộ nhớ tiềm năng, tùy thuộc vào cách thức và nơi hệ thống lưu trữ các thư viện.

Một khung công tác giống như một thư viện động, nhưng có thể chứa các tài nguyên trong cấu trúc thư mục của nó (hình ảnh, âm thanh, các khung khác, v.v.). Trong trường hợp này, một thư viện tĩnh hoặc tệp .dylib đơn giản sẽ không cắt nó để bạn có thể phải liên kết với một khung để có thể tìm thấy những gì nó cần để chạy đúng.

Khi bạn liên kết với khung của bên thứ ba (giả sử thứ gì đó bạn đã tải xuống từ github và tự xây dựng), nó có thể không xuất hiện trên hệ thống mà bạn định chạy. Trong trường hợp này, bạn không chỉ liên kết với khung mà còn nhúng nó vào gói ứng dụng của bạn bằng cách sử dụng giai đoạn "Sao chép khung". Khi chương trình của bạn chạy, trình liên kết thời gian chạy (còn gọi là trình phân giải) sẽ nhìn vào bên trong gói của bạn ngoài đường dẫn trình tải hệ thống, tìm khung nhúng và liên kết nó để ứng dụng của bạn sẽ có mã cần chạy.

Cuối cùng, "nhị phân nhúng" đúng là một thực thi mà cả hai bạn đã nhúng trong gói ứng dụng của mình thông qua Giai đoạn sao chép tệp và bạn tự thực hiện, có thể bằng một cuộc gọi đến popen()hoặc tương tự. Chương trình nhị phân nhúng có thể được gọi bởi chương trình của bạn, nhưng nó không được liên kết với nó. Nó là một thực thể hoàn toàn bên ngoài (như các chương trình trong /binthư mục).

Trong thực tế, đối với các thư viện và khung do hệ thống cung cấp, bạn sẽ liên kết với chúng và đó là tất cả những gì bạn cần làm.

Nếu bạn cần liên kết một thư viện mà bạn đã xây dựng mà không cần bất kỳ tài nguyên nhúng nào (nghĩa là không yêu cầu tồn tại khung), thì bạn chỉ có thể liên kết với thư viện tĩnh. Nếu bạn thấy bạn có nhiều mô-đun trong chương trình muốn sử dụng cùng một mã thư viện, thì việc chuyển đổi nó thành khung hoặc thư viện động và liên kết với điều đó có thể tiết kiệm không gian và có thể thuận tiện (đặc biệt nếu việc sử dụng bộ nhớ là vấn đề đáng lo ngại).

Cuối cùng, các khung có thể bao gồm không chỉ các tài nguyên, mà cả các tệp tiêu đề và / hoặc giấy phép. Sử dụng một khung để truyền tải các tệp này thực sự là một cơ chế phân phối thuận tiện, do đó, bạn thường muốn kết hợp một khung chỉ để những thứ này có thể được gắn thẻ cùng với nhị phân của bạn (nghĩa là các yêu cầu cấp phép có thể bắt buộc điều này).

--- BIÊN TẬP ---

Adam Johns đã đăng câu hỏi sau đây như một bình luận:

Đây là một câu trả lời tuyệt vời. Có một cái gì đó tôi vẫn còn một chút bối rối, tuy nhiên. Việc tự thực hiện nhị phân có nghĩa là gì? Bạn có nghĩa là chỉ đơn giản là sử dụng mã của khung nhúng? Tôi biết bạn đã đề cập đến popen (), nhưng bạn đang nói ứng dụng của tôi đang gọi popen ()? Tôi thực sự không biết điều đó có nghĩa là gì.

Tôi đang nói một tệp nhị phân nhúng chỉ là một tệp tài nguyên khác trong gói của bạn, như tệp âm thanh hoặc hình ảnh, mặc dù tệp thay vào đó là một công cụ dòng lệnh thực thi. Các popen()chức năng ( man popentừ thiết bị đầu cuối của bạn để đọc thêm về nó) cho phép bạn thực hiện các chương trình tùy ý từ một chương trình đang chạy. Các system()chức năng là một cách khác. Có những cái khác, và tôi sẽ đưa ra một ví dụ lịch sử ở đây có thể giúp hiểu rõ hơn về việc sử dụng nhị phân nhúng rõ ràng hơn một chút:

Như bạn có thể biết, khi bạn khởi chạy một ứng dụng trên Mac OS X, nó được khởi chạy với id người dùng của người dùng hiện tại. Trong hầu hết các cài đặt phổ biến đó là người dùng mặc định tại máy tính để bàn admin, người được cấp id người dùng 501.

Trên các hệ điều hành dựa trên Unix, chỉ rootngười dùng (id người dùng 0) có toàn quyền truy cập vào toàn bộ hệ thống tệp. Đôi khi, một chương trình cài đặt được khởi chạy bởi người dùng Desktop cần cài đặt các tệp trong một thư mục đặc quyền (ví dụ như trình điều khiển). Trong trường hợp này, chương trình ứng dụng cần tăng các đặc quyền của nó cho rootngười dùng để nó có thể ghi vào các thư mục bị hạn chế này.

Để tạo điều kiện thuận lợi cho hệ điều hành này thông qua OS X 10.7, Apple đã cung cấp trong API dịch vụ ủy quyền của mình chức năng AuthorizationExecuteWithPriv đặc quyền () (hiện tại không dùng nữa, nhưng vẫn là một ví dụ hữu ích).

AuthorizationExecuteWithPrivileges()lấy làm đối số một đường dẫn đến một công cụ dòng lệnh để thực thi như root. Công cụ dòng lệnh là một tập lệnh shell thực thi hoặc nhị phân được biên dịch mà bạn đã viết để chạy logic cài đặt của mình. Công cụ này đã được cài đặt bên trong gói ứng dụng của bạn giống như bất kỳ tệp tài nguyên nào khác.

Khi được gọi, HĐH sẽ đưa ra hộp thoại ủy quyền yêu cầu mật khẩu của người dùng (bạn đã thấy điều này trước đây!) Và khi được nhập sẽ thực hiện chương trình như rootnhân danh ứng dụng của bạn. Quá trình này tương tự như chỉ thực hiện một chương trình với popen()chính bạn, mặc dù popen()một mình không mang lại cho bạn lợi ích của việc leo thang đặc quyền.


62
Làm thế nào để bạn biết những điều này?
Ian Warburton

56
@IanWarburton Tôi đã lập trình các hệ điều hành của Apple trong hơn 20 năm và đã chọn được một vài mẩu tin ở đây và đó. :)
mệnh

1
@JustAMartin Ý tôi là link, nhưng bạn đúng là bạn cũng phải nhúng nó qua giai đoạn sao chép tệp (nếu không bạn sẽ sử dụng nó như thế nào?). Mục tiêu của việc sử dụng khung bên thứ ba hoặc nhị phân nhúng là thực thi mã mà thực thể cung cấp. Với một nhị phân nhúng, không có liên kết có liên quan. Trong thời gian chạy, bạn xây dựng một đường dẫn đến nhị phân sau đó thực hiện thủ công. Với khung, trình liên kết thời gian biên dịch sẽ liên kết nó khi bạn xây dựng ứng dụng của mình, sau đó (nếu là khung của bên thứ 3), bạn nhúng nó qua giai đoạn sao chép tệp và cuối cùng trình liên kết thời gian chạy liên kết lại khi bạn chạy ứng dụng của mình .
mệnh

1
Những điều này không rõ ràng như những gì bạn đã trả lời với @JustAMartin. Mục tiêu của việc sử dụng khung bên thứ ba hoặc nhị phân nhúng là thực thi mã mà thực thể cung cấp. Ngày nay, các tệp nhị phân nhúng cũng có thể là khung của bên thứ ba. Tôi đang cố gắng hiểu ý của bạn ở đây ... AFA Tôi hiểu, các nhị phân nhúng có nghĩa là, nhị phân riêng biệt của khung được nhúng sẽ được đưa vào gói Ứng dụng, và nếu bạn chỉ liên kết cùng một khung thì nó sẽ đặt nó vào cùng một nhị phân như đó là ứng dụng. Xin hãy sửa tôi nếu tôi sai ...
hariszaman

1
Có thể có ma thuật Xcode mới sẽ tải một khung nhúng. Đã được một thời gian kể từ khi tôi cần chức năng đó. Nếu bạn muốn khám phá những gì đang diễn ra nhiều hơn xin vui lòng gửi một câu hỏi mới ở đây trên SO.
mệnh

35

Nói ngắn gọn,

  • thư viện hệ thống, liên kết chúng;
  • Thư viện bên thứ 3, nhúng chúng.

tại sao?

  • nếu bạn cố gắng nhúng các thư viện hệ thống, bạn sẽ không tìm thấy chúng trong danh sách bật lên;
  • nếu bạn liên kết các thư viện của bên thứ 3, rất có thể bạn sẽ gặp sự cố.

7

Đây là một phần của Dependencyquản lý [Giới thiệu]

Xin lưu ý rằng Xcode 11chỉ chứa Frameworks, Libraries, and Embedded Contentphần trong Generaltab

Liên kết nhị phân

Build Phases -> Link Binary With Librarieslà một tấm gương của General -> Linked Frameworks and Libraries.

Thư viện và khung tĩnh

Nếu bạn thêm một Static Library or Static Frameworkphần vào phần này, nó sẽ xuất hiện trong Frameworks nhóm [Giới thiệu] ( Project Navigator -> <workspace/project> -> Frameworks) và sẽ có một tham chiếu được thêm vào dự án của bạn cho nó. Sau đó, nó sẽ được sử dụng bởi Static Linker. Static Linkertại thời gian biên dịch sẽ bao gồm / sao chép tất cả mã từ thư viện vào tệp đối tượng thực thi. Static linkerlàm việc theo cặp vớiBuild Settings -> <Library/Framework> Search Paths

Static Library

Static Framework

  • Build Settings -> Framework Search Paths. Nếu bạn không thêm static frameworkphần này vào phần này, bạn sẽ gặp lỗi biên dịch [Không có mô-đun như vậy]

Nhúng nhị phân

Thư viện tĩnh và khung tĩnh

Nhúng sẽ không có ý nghĩa gì đối với a Static LibraryStatic Frameworkbởi vì các biểu tượng từ chúng được biên dịch thành nhị phân thực thi. Xcode sẽ không cho phép bạn thả xuống static librarydưới phần Nhúng.

Khung động

Build Phases -> Embed Frameworkslà một tấm gương của General -> Embedded Binaries. Nhúng thực sự thêm một bản sao của khung vào gói ứng dụng của bạn. Kết quả là, khi một khung được thêm / xóa vào Embedphần, nó sẽ tự động được thêm / xóa vào Linkedphần. Theo mặc định, thư mục của gói là Frameworksnhưng bạn có thể thay đổi nó bằng cách sử dụng Destinationtrường. Hơn nữa, bạn có thể chỉ định a Subpath.

Dynamic linker :dyldkhi tải hoặc thời gian chạy sẽ cố gắng tìm khung nhúng bằng cách sử dụng @rpath[Giới thiệu] Nếu không tìm thấy lỗi sẽ xảy ra [dyld: Thư viện không được tải]

[Khi sử dụng Liên kết và Nhúng]

[Từ vựng]

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.