DLL là gì và nó hoạt động như thế nào?


86

Tôi luôn tham khảo các tệp DLL trong mã C # của mình, nhưng chúng vẫn còn là một bí ẩn mà tôi muốn làm rõ. Đây là một loại câu hỏi dồn dập liên quan đến DLL.

Tôi hiểu DLL là một thư viện được liên kết động có nghĩa là một chương trình khác có thể truy cập thư viện này tại thời điểm chạy để có được "chức năng". Tuy nhiên, hãy xem xét dự án ASP.NET sau với Web.dllBusiness.dll( Web.dlllà chức năng giao diện người dùng và nó tham chiếu Business.dllcho các kiểu và phương thức).

  1. Tại thời điểm những gì Web.dlltự động liên kết đến Business.dll? Bạn nhận thấy rất nhiều lỗi trong Windows HDD cho các tác vụ dường như nhỏ khi sử dụng Word (v.v.) và tôi nghĩ rằng Word đang tắt và liên kết động trong chức năng từ các DLL khác?

    1a. Ngoài ra, những gì tải và liên kết DLL - hệ điều hành hoặc một số khung thời gian chạy như .NET framework?

    1b. Quá trình "liên kết" là gì? Kiểm tra tính tương thích có được thực hiện không? Đang tải vào cùng một bộ nhớ? Liên kết thực sự có nghĩa là gì?

  2. Điều gì thực sự thực thi mã trong DLL? Nó có được thực thi bởi bộ xử lý hay có một giai đoạn dịch hoặc biên dịch khác trước khi bộ xử lý hiểu mã bên trong DLL không?

    2a. Trong trường hợp một DLL được xây dựng trong C # .NET, cái gì đang chạy: .NET framework hay trực tiếp hệ điều hành?

  3. DLL từ Linux có hoạt động trên hệ thống Windows (nếu điều đó tồn tại) hay chúng là hệ điều hành cụ thể?

  4. Các DLL có cụ thể cho một khuôn khổ cụ thể không? Một DLL được xây dựng bằng C # .NET có thể được sử dụng bởi DLL được xây dựng với, chẳng hạn như Borland C ++ không?

    4a. Nếu câu trả lời cho 4 là "không" thì điểm của một DLL là gì? Tại sao các khung công tác khác nhau không sử dụng các định dạng riêng của chúng cho các tệp được liên kết? Ví dụ: .exe được tích hợp trong .NET biết rằng loại tệp .abc là thứ mà nó có thể liên kết vào mã của nó.

  5. Trở lại với Web.dll/ Business.dllVí dụ - để có được một kiểu lớp của khách hàng tôi cần phải tham khảo Business.dlltừ Web.dll. Điều này phải có nghĩa là Business.dllchứa một số loại đặc điểm kỹ thuật về lớp khách hàng thực sự là gì. Nếu tôi đã biên dịch Business.dlltệp của mình trong, chẳng hạn như Delphi: liệu C # có hiểu nó và có thể tạo một lớp khách hàng không, hoặc có một số loại thông tin tiêu đề hoặc một cái gì đó có nội dung "xin lỗi, bạn chỉ có thể sử dụng tôi từ Delphi DLL khác" ?

    5a. Áp dụng tương tự cho các phương pháp; tôi có thể viết một CreateInvoice()phương thức trong DLL, biên dịch nó bằng C ++, sau đó truy cập và chạy nó từ C # không? Điều gì ngăn cản hoặc cho phép tôi làm điều này?

  6. Về chủ đề chiếm quyền điều khiển DLL, chắc chắn DLL thay thế (xấu) phải chứa các chữ ký và kiểu phương thức chính xác như kiểu và chữ ký phương thức đang bị tấn công. Tôi cho rằng điều này sẽ không khó thực hiện nếu bạn có thể tìm ra những phương pháp có sẵn trong DLL gốc.

    6a. Điều gì trong chương trình C # của tôi đang quyết định xem tôi có thể truy cập vào một DLL khác không? Nếu DLL bị tấn công của tôi chứa chính xác các phương thức và kiểu như bản gốc nhưng nó được biên dịch bằng ngôn ngữ khác, thì nó có hoạt động không?

Nhập DLL và đăng ký DLL là gì?


21
Câu hỏi này có thể đang yêu cầu câu trả lời dài nhất trong lịch sử SO.
Matti Virkkunen

4
Đáng lẽ nó phải có 12 câu hỏi riêng biệt.
Henk Holterman

2
Đây là một câu hỏi tuyệt vời, nhưng tôi thực sự đồng ý với @Chaos và @Matti. Câu hỏi này cần tập trung hơn và có thể / nên được chia thành một số câu hỏi khác nhau.
Chris Thompson

3
Đó là một chút của một bãi não khi tôi đã viết nó + Tôi muốn tập trung kiến thức trong một khu vực :)
Remotec

1
Bây giờ sẽ là một wiki cộng đồng.
leppie

Câu trả lời:


74

Trước hết, bạn cần hiểu sự khác biệt giữa hai loại DLL rất khác nhau. Microsoft đã quyết định sử dụng cùng một phần mở rộng tệp (.exe và .dll) với cả .NET (mã được quản lý) và mã gốc, tuy nhiên các tệp DLL mã được quản lý và các tệp DLL gốc rất khác nhau bên trong.

1) Web.dll liên kết động với business.dll ở điểm nào? Bạn nhận thấy rất nhiều lỗi trong Windows HDD cho các tác vụ dường như nhỏ khi sử dụng Word, v.v. và tôi nghĩ rằng Word này sẽ tắt và liên kết động trong chức năng từ các DLL khác?

1) Trong trường hợp .NET, các tệp DLL thường được tải theo yêu cầu khi phương thức đầu tiên cố gắng truy cập bất kỳ thứ gì từ DLL được thực thi. Đây là lý do tại sao bạn có thể nhận TypeNotFoundExceptions ở bất kỳ đâu trong mã của mình nếu không tải được DLL. Khi một cái gì đó như Word đột nhiên bắt đầu truy cập nhiều vào ổ cứng, nó có khả năng bị hoán đổi (lấy dữ liệu đã được hoán đổi sang đĩa để tạo chỗ trống trong RAM)

1a) Ngoài ra, những gì tải và liên kết DLL - O / S hoặc một số khuôn khổ thời gian chạy như .Net framework?

1a) Trong trường hợp các DLL được quản lý, .NET framework là thứ tải, JIT biên dịch (biên dịch mã bytecode .NET thành mã gốc) và liên kết các DLL. Trong trường hợp các DLL gốc, nó là một thành phần của hệ điều hành tải và liên kết DLL (không cần biên dịch vì các DLL gốc đã chứa mã gốc).

1b) Quá trình “liên kết” là gì? Kiểm tra xem có tính tương thích không? Đang tải vào cùng một bộ nhớ? Liên kết thực sự có nghĩa là gì?

1b) Liên kết là khi các tham chiếu (ví dụ: cuộc gọi phương thức) trong mã gọi đến các ký hiệu (ví dụ: phương thức) trong DLL được thay thế bằng địa chỉ thực của các thứ trong DLL. Điều này là cần thiết vì địa chỉ cuối cùng của những thứ trong DLL không thể được biết trước khi nó được tải vào bộ nhớ.

2) Điều gì thực sự thực thi mã trong DLL? Nó có được thực thi bởi bộ xử lý hay có một giai đoạn dịch hoặc biên dịch khác trước khi bộ xử lý hiểu mã bên trong DLL không?

2) Trên Windows, tệp .exe và tệp .dll khá giống nhau. Các tệp .exe và .dll gốc chứa mã gốc (cùng một thứ mà bộ xử lý thực thi), vì vậy không cần phải dịch. Các tệp .exe và .dll được quản lý chứa .NET bytecode là mã JIT đầu tiên được biên dịch (được dịch sang mã gốc).

2a) Trong trường hợp một DLL được xây dựng từ C # .net, cái gì đang chạy cái này? .Net framework hay hệ điều hành trực tiếp?

2a) Sau khi mã đã được biên dịch JIT, nó sẽ chạy theo cách chính xác như bất kỳ mã nào.

3) Liệu một DLL từ Linux có hoạt động trên hệ thống Windows (nếu điều đó tồn tại) hay chúng là hệ điều hành cụ thể?

3) Các DLL được quản lý có thể hoạt động như hiện tại, miễn là các khuôn khổ trên cả hai nền tảng đều được cập nhật và bất kỳ ai đã viết DLL không cố tình phá vỡ khả năng tương thích bằng cách sử dụng các cuộc gọi gốc. Các DLL gốc sẽ không hoạt động như trong, vì các định dạng khác nhau (mặc dù mã máy bên trong là giống nhau, nếu cả hai đều cho cùng một nền tảng bộ xử lý). Nhân tiện, trên Linux, "DLL" được gọi là tệp .so (đối tượng được chia sẻ).

4) Chúng có cụ thể cho một khuôn khổ cụ thể không? DLL được xây dựng bằng C # .Net có thể được sử dụng bởi DLL được xây dựng bằng Borland C ++ (chỉ ví dụ)?

4) Các tệp DLL được quản lý chỉ dành riêng cho khung công tác .NET, nhưng tự nhiên chúng hoạt động với bất kỳ ngôn ngữ tương thích nào. Các tệp DLL gốc tương thích với điều kiện là mọi người đều sử dụng các quy ước giống nhau (gọi quy ước (cách các đối số hàm được truyền ở cấp mã máy), đặt tên ký hiệu, v.v.)

5) Quay lại ví dụ web.dll / business.dll. Để có được loại khách hàng đẳng cấp, tôi cần tham khảo business.dll từ web.dll. Điều này có nghĩa là business.dll chứa một đặc điểm kỹ thuật của một số loại khách hàng thực sự là gì. Nếu tôi đã biên dịch tệp business.dll của mình nói rằng Delphi sẽ C # hiểu nó và có thể tạo một lớp khách hàng - hoặc có một số loại thông tin tiêu đề hoặc một cái gì đó nói "xin lỗi, bạn chỉ có thể sử dụng tôi từ một dll delphi khác" .

5) Các DLL được quản lý chứa mô tả đầy đủ về mọi lớp, phương thức, trường, v.v. mà chúng chứa. AFAIK Delphi không hỗ trợ .NET, vì vậy nó sẽ tạo các tệp DLL gốc, không thể sử dụng trong .NET ngay lập tức. Bạn có thể gọi các hàm với PInvoke, nhưng sẽ không tìm thấy định nghĩa lớp. Tôi không sử dụng Delphi vì vậy tôi không biết cách nó lưu trữ thông tin kiểu với các tệp DLL. Ví dụ: C ++ dựa trên các tệp tiêu đề (.h) chứa các khai báo kiểu và phải được phân phối với DLL.

6) Về chủ đề chiếm quyền điều khiển DLL, chắc chắn tệp DLL thay thế (xấu) phải chứa các chữ ký phương thức chính xác, các loại như ký hiệu đang bị chiếm quyền điều khiển. Tôi cho rằng điều này sẽ không khó thực hiện nếu bạn có thể tìm ra những phương pháp nào, v.v. có sẵn trong DLL gốc.

6) Thật vậy, không khó để thực hiện nếu bạn có thể dễ dàng chuyển đổi DLL. Việc ký mã có thể được sử dụng để tránh điều này. Để ai đó thay thế một DLL đã ký, họ sẽ phải biết khóa ký mà nó giữ bí mật.

6a) Một chút câu hỏi lặp lại ở đây nhưng điều này quay trở lại những gì trong chương trình C # của tôi đang quyết định xem tôi có thể truy cập vào một DLL khác không? Nếu DLL bị tấn công của tôi chứa chính xác các phương thức và kiểu như bản gốc nhưng nó được biên dịch trong một lanugage khác thì nó có hoạt động không?

6a) Nó sẽ hoạt động miễn là nó là một DLL được quản lý, được tạo bằng bất kỳ ngôn ngữ .NET nào.

  • Nhập DLL là gì? và đăng ký dll?

"Nhập DLL" có thể có nhiều nghĩa, thông thường nó có nghĩa là tham chiếu đến một tệp DLL và sử dụng những thứ trong đó.

Đăng ký DLL là việc được thực hiện trên Windows để đăng ký toàn cầu các tệp DLL dưới dạng thành phần COM để cung cấp chúng cho bất kỳ phần mềm nào trên hệ thống.


3
Tôi muốn thêm vào # 4 rằng .NET có thể dịch các tệp DLL để chúng tương thích với bất kỳ chương trình gốc nào hiểu / sử dụng COM (Mô hình đối tượng chung). Câu trả lời rất tốt tho.
MerickOWA

7

Tệp .dll chứa mã đã biên dịch mà bạn có thể sử dụng trong ứng dụng của mình.

Đôi khi công cụ được sử dụng để biên dịch .dll quan trọng, đôi khi không. Nếu bạn có thể tham chiếu .dll trong dự án của mình, không quan trọng công cụ nào đã được sử dụng để viết mã các chức năng tiếp xúc của .dll.

Liên kết xảy ra trong thời gian chạy, không giống như các thư viện được liên kết tĩnh, chẳng hạn như các lớp của bạn, liên kết vào thời gian biên dịch.

Bạn có thể coi .dll như một hộp đen cung cấp thứ mà ứng dụng của bạn cần mà bạn không muốn tự viết. Có, ai đó hiểu chữ ký của .dll có thể tạo một tệp .dll khác với mã khác bên trong nó và ứng dụng gọi điện của bạn không thể biết sự khác biệt.

HTH


6

1) Web.dll liên kết động với business.dll ở điểm nào? Bạn nhận thấy rất nhiều lỗi trong Windows HDD cho các tác vụ dường như nhỏ khi sử dụng Word, v.v. và tôi nghĩ rằng Word này sẽ tắt và liên kết động trong chức năng từ các DLL khác?

1) Tôi nghĩ rằng bạn đang nhầm lẫn giữa liên kết với tải. Liên kết là khi tất cả các kiểm tra và số dư được kiểm tra để đảm bảo rằng những gì được yêu cầu đều có sẵn. Tại thời điểm tải, các phần của dll được tải vào bộ nhớ hoặc được hoán đổi sang tệp trang. Đây là hoạt động HD mà bạn đang xem.

Liên kết động khác với liên kết tĩnh ở chỗ trong liên kết tĩnh, tất cả mã đối tượng được đưa vào .exe chính tại thời điểm liên kết. Với liên kết động, mã đối tượng được đưa vào một tệp riêng (dll) và nó được tải vào thời điểm khác với .exe.

Liên kết động có thể là ẩn (tức là ứng dụng liên kết với lib nhập) hoặc rõ ràng (tức là ứng dụng sử dụng LoadLibrary (ví dụ) để tải dll).

Trong trường hợp ngầm định, / DELAYLOAD có thể được sử dụng để hoãn việc tải dll cho đến khi ứng dụng thực sự cần nó. Nếu không, ít nhất một số phần của nó được tải (ánh xạ vào không gian địa chỉ quy trình) như một phần của quá trình bắt đầu quy trình. Dll cũng có thể yêu cầu nó không bao giờ được dỡ bỏ trong khi tiến trình đang hoạt động.

COM sử dụng LoadLibrary để tải COM dlls. Lưu ý rằng ngay cả trong trường hợp ngầm định, hệ thống đang sử dụng một thứ tương tự như LoadLibrary để tải dll khi khởi động quy trình hoặc trong lần sử dụng đầu tiên.

2) Điều gì thực sự thực thi mã trong DLL? Nó có được thực thi bởi bộ xử lý hay có một giai đoạn dịch hoặc biên dịch khác trước khi bộ xử lý hiểu mã bên trong DLL không?

2) Hình nhân chứa mã đối tượng giống như .exes. Định dạng của tệp dll gần giống với định dạng của tệp exe. Tôi đã nghe nói rằng chỉ có một chút khác nhau trong tiêu đề của hai tệp.

Trong trường hợp DLL được xây dựng từ C # .net, .Net framework đang chạy nó.

3) Liệu một DLL từ Linux có hoạt động trên hệ thống Windows (nếu điều đó tồn tại) hay chúng là hệ điều hành cụ thể?

3) DLL là nền tảng cụ thể.

4) Chúng có cụ thể cho một khuôn khổ cụ thể không? DLL được xây dựng bằng C # .Net có thể được sử dụng bởi DLL được xây dựng bằng Borland C ++ (chỉ ví dụ)?

4) Hình nền có thể tương thích với các khuôn khổ khác nếu được chăm sóc đặc biệt hoặc một số mã keo bổ sung được viết.

Dlls rất hữu ích khi một công ty bán nhiều sản phẩm có khả năng chồng chéo. Ví dụ: tôi duy trì một dll raster i / o được sử dụng bởi hơn 30 sản phẩm khác nhau tại công ty. Nếu bạn đã cài đặt nhiều sản phẩm, một lần nâng cấp dll có thể nâng cấp tất cả các sản phẩm lên định dạng raster mới.

5) Quay lại ví dụ web.dll / business.dll. Để có được loại khách hàng đẳng cấp, tôi cần tham khảo business.dll từ web.dll. Điều này có nghĩa là business.dll chứa một đặc điểm kỹ thuật của một số loại khách hàng thực sự là gì. Nếu tôi đã biên dịch tệp business.dll của mình nói rằng Delphi sẽ C # hiểu nó và có thể tạo một lớp khách hàng - hoặc có một số loại thông tin tiêu đề hoặc một cái gì đó nói "xin lỗi, bạn chỉ có thể sử dụng tôi từ một dll delphi khác" .

5) Tùy thuộc vào nền tảng, các khả năng của dll được trình bày theo nhiều cách khác nhau, thông qua tệp .h, tệp .tlb hoặc các cách khác trên .net.

6) Về chủ đề chiếm quyền điều khiển DLL, chắc chắn tệp DLL thay thế (xấu) phải chứa các chữ ký phương thức chính xác, các loại như ký hiệu đang bị chiếm quyền điều khiển. Tôi cho rằng điều này sẽ không khó thực hiện nếu bạn có thể tìm ra những phương pháp nào, v.v. có sẵn trong DLL gốc.

6) dumpbin / xuất và câm / nhập là các công cụ thú vị để sử dụng trên .exe và .dlls


3) DLL là nền tảng cụ thể
Henk Holterman
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.