2009-08-18 34 views
17

Tôi tự hỏi tại sao người liên kết không thể thực hiện công việc của họ đơn giản bằng cách tham khảo thông tin trong các tệp .dll thực tế có mã triển khai thực tế? tôi có nghĩa là tại sao linkers vẫn cần các tập tin .lib để làm liên kết ngầm?Tại sao chúng ta vẫn cần tệp .lib stub khi chúng tôi có triển khai .dll thực tế?

không phải là bảng địa chỉ xuất và tương đối đủ cho liên kết như vậy?

có cách nào để người dùng có thể thực hiện liên kết ngầm bằng cách sử dụng chỉ .dll mà không có tệp .lib stub/proxy?

tôi nghĩ rằng các cửa sổ thực thi bộ tải sẽ chỉ đơn giản là làm LoadLibrary/LoadLibraryEx cuộc gọi thay mặt cho chương trình (do đó tên liên kết ngầm) đó là sự khác biệt chính để liên kết rõ ràng. nếu điều đó là đúng thì làm nó một cách rõ ràng mà không có .lib nên chỉ ra rằng nó là doable mà không có nó ngầm, phải không? hoặc tôi chỉ nói không có ý nghĩa?

bất kỳ sự giúp đỡ được đánh giá cao, cảm ơn nhiều :)

geeko

Trả lời

7

tôi có thể nghĩ đến một vài lý do.

  • Sử dụng các tệp .lib có nghĩa là bạn có thể tạo phiên bản DLL khác với hệ thống của mình, miễn là bạn đã cài đặt đúng SDK.
  • Trình biên dịch & trình liên kết cần hỗ trợ biên dịch đa nền tảng - Bạn có thể xây dựng cho một mục tiêu 64 bit trên nền tảng 32 bit và ngược lại và không có đúng kiến ​​trúc DLL hiện tại.
  • . Các tệp .lib cho phép bạn "ẩn" một số phần nhất định trong quá trình triển khai của mình - bạn có thể xuất riêng tư không hiển thị trong .lib nhưng có thể khám phá được thông qua GetProcAddress. Bạn cũng có thể làm xuất khẩu thứ tự trong trường hợp chúng không có tên thân thiện được xuất, nhưng sẽ có một tên thân thiện trong .lib.
  • DLL gốc không có tên mạnh, vì vậy có thể nhận phiên bản sai của DLL.
  • Và quan trọng nhất, công nghệ này được thiết kế vào những năm 1980. Nếu nó được thiết kế ngày nay, nó có lẽ sẽ gần gũi hơn với những gì bạn mô tả - ví dụ, .NET bạn chỉ cần tham chiếu đến assembly đích và bạn có mọi thứ bạn cần để sử dụng nó.

Tôi không biết cách nào để liên kết ngầm chỉ với DLL - Tìm kiếm nhanh đã tiết lộ một số công cụ, nhưng tôi chưa sử dụng bất kỳ công cụ nào trong số đó.

Trong trường hợp này, tôi sẽ tạo một tệp nguồn riêng với các hàm bạn cần sử dụng và tự động tải tệp DLL và liên kết chúng khi cần. Ví dụ:

// using global variables and no-error handling for brevity. 

HINSTANCE theDll = NULL; 
typedef void (__stdcall * FooPtr)(); 
FooPtr pfnFoo = NULL; 
INIT_ONCE initOnce; 

BOOL CALLBACK BindDLL(PINIT_ONCE initOnce, PVOID parameter, PVOID context) 
{ 
    theDll = LoadLibrary(); 
    pfnfoo = GetProcAddress(dll, "Foo"); 

    return TRUE; 
} 

// Export for foo 
void Foo() 
{ 
    // Use one-time init for thread-safe lazy initialization 
    InitOnceExecuteOnce(initOnce, BinDll, NULL, NULL) 
    pfnFoo(); 
} 
+0

cảm ơn bạn Micael, bạn đã trả lời khá nhiều câu hỏi của tôi ngoại trừ một: có cách nào để liên kết ngầm chỉ sử dụng tệp .dll triển khai không? cảm ơn bạn một lần nữa – geeko

+0

tôi thực sự đánh giá cao công việc của bạn Michael. nhưng mã đó là để liên kết rõ ràng. bạn vui lòng viết tên của những công cụ này? hoặc ít nhất là truy vấn bạn đã sử dụng để truy cập chúng? – geeko

+0

Truy vấn chỉ là "Tạo lib từ dll", một trong những lần truy cập hàng đầu là một dự án dựa trên codeproject. – Michael

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