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 để nó 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 /bin
thư 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 popen
từ 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ỉ root
ngườ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 root
ngườ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ư root
nhâ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.