2010-02-25 29 views
7

Tôi đang làm việc trên một ứng dụng Windows (EXE) sử dụng nhiều DLL. Phát triển là trong VCExpress 2005 (VC 8.0), chỉ sử dụng C.LoadLibrary() không tải được DLL với tệp kê khai và riêng tư

Một số các tệp DLL này là các trình cắm thêm/tiện ích/tiện ích được tải động bằng cách sử dụng LoadLibrary theo tệp cấu hình được đọc bởi EXE.

Quan trọng: ứng dụng phải di động (theo nghĩa có thể chạy từ ổ flash USB hoặc tương tự mà không cần cài đặt) và DLL trình cắm thêm có thể không nằm trong cùng thư mục với ứng dụng EXE (lý do cũ)).

Với MSVC6 điều này đơn giản: biên dịch, liên kết, phân phối EXE và DLL.

Với MSVC8 Thư viện thời gian chạy C (MSVCRT) không còn được phân phối với hệ điều hành, do đó, người ta không thể dựa vào nó đang được cài đặt. Để đáp ứng yêu cầu về tính di động, tôi cần sử dụng private assembly. Tất cả các EXE và DLL đã có các biểu hiện của chúng được nhúng vào.

Vấn đề của tôi: các DLL plug-in nạp qua LoadLibrary() không tìm ra private assembly đó là trong thư mục của EXE, vì vậy cố gắng để tải chúng thất bại trừ khi lắp ráp Microsoft.VC80.CRT được cài đặt trong winsxs.

Sản phẩm bắt giữ: nếu tệp kê khai bị xóa khỏi plugin trình cắm thêm DLL, mọi thứ đều hoạt động.

Câu hỏi của tôi:

  1. Trong trường hợp vấn đề, Windows dường như không thể sau một trong hai Assembly searching sequence hoặc Dynamic link library search order. Cụ thể là nó đang tìm kiếm assembly riêng trong đường dẫn mà từ đó DLL đã được nạp, không phải từ đó ứng dụng (EXE) được nạp.
    Tôi đã cố gắng xác minh điều này bằng cách đặt lắp ráp liền kề với tệp DLL và thay đổi thư mục hiện tại (để loại trừ các trường hợp thư mục hoạt động) và nhận được hành vi mong muốn. Bất cứ ai khác có thể xác nhận rằng đây là hành vi bình thường khi sử dụng LoadLibrary với SxS?

  2. Tôi có giả định rằng nếu không có tệp kê khai, DLL rơi trở lại thứ tự tải không SxS đang tìm kiếm msvcr80.dll (chứ không phải tệp kê khai Microsoft.VC80.CRT.manifest) trong thư mục EXE?

  3. Nếu tôi đúng về (1) và (2), tôi sẽ mất gì khi chỉ loại trừ tệp kê khai khỏi tệp DLL? Rephrased, tại sao tôi không nên giải quyết vấn đề của tôi bằng cách chỉ loại trừ các biểu hiện?

Trả lời

0

Liên kết tĩnh với CRT. Miễn là bạn không sử dụng .Net trong ứng dụng của bạn (pure C/C++), nó có thể liên kết tĩnh với CRT.

Việc giới thiệu .Net trong ứng dụng của tôi đã buộc tôi phải chuyển từ CRT được liên kết tĩnh thành CRT được liên kết động. Tôi cũng đã cố gắng để tìm một cách để tham khảo các DLL CRT tại địa phương mà không cần phải cài đặt chúng một cách rõ ràng, nhưng tôi đã không tìm thấy nó. Do đó, nếu có thể, liên kết tĩnh với CRT.

+0

Cảm ơn - Tôi thấy rằng http://stackoverflow.com/questions/238465 và http://stackoverflow.com/questions/787216 cũng thảo luận về giá trị tương đối của liên kết tĩnh và động. Tôi do dự khi sử dụng liên kết tĩnh vì tôi không chắc chắn rằng API không cho phép/mong đợi phân bổ tài nguyên và phân phối xảy ra trong các mô-đun khác nhau, điều này sẽ làm hỏng ứng dụng. Ngoài ra liên kết tĩnh sẽ dẫn đến các tập tin nhị phân cồng kềnh. – Twylite

10

Bạn cần hiểu bối cảnh kích hoạt là gì để hiểu vấn đề này.

Một exe, hoặc dll, với tệp kê khai, có ngữ cảnh kích hoạt - ngữ cảnh kích hoạt là danh sách các lớp cửa sổ, hội đồng phụ thuộc, dll và đăng ký tham chiếu miễn phí được phát hiện khi tệp kê khai được phân tích cú pháp.

Một exe, hoặc dll, không có tệp kê khai, sử dụng ngữ cảnh kích hoạt mặc định của quy trình - thường là ngữ cảnh kích hoạt của exe nếu exe có ngữ cảnh kích hoạt.

Trong trường hợp của bạn, dll có ngữ cảnh kích hoạt riêng - vì nó có tệp kê khai. Và nó luôn luôn là đường dẫn đến tệp tin (tệp/thư mục chứa tệp kê khai) được tìm kiếm cho các hội đồng.

Đó là lý do tại sao các cửa sổ bắt đầu bằng cách tìm kiếm thư mục của dll để lắp ráp riêng. Sau đó, khi thất bại, Windows tìm kiếm đường dẫn tìm kiếm thư viện tải tiêu chuẩn cho dll: bắt đầu bằng thư mục gốc của exe. Nhưng tìm kiếm của nó cho dll bây giờ, không hội đồng - do đó, thư mục lắp ráp có chứa các dll không được tìm thấy.

  1. No. Nếu không có tệp kê khai, dll sẽ quay lại sử dụng ngữ cảnh kích hoạt mặc định: tệp kê khai của exe. This Blog Article giải thích một chút.

  2. Loại trừ tệp kê khai. Những gì bạn mất là khả năng để có được dll để xác định hội đồng phụ thuộc của riêng mình. Những gì bạn cần làm do đó, là thêm bất kỳ hội đồng phụ thuộc các nhu cầu dll, để các biểu hiện ứng dụng.

+0

Một điểm cần thêm - trình tải dường như bỏ qua thư mục cục bộ của ứng dụng khi tệp kê khai được nhúng chứa tham chiếu publicKeyToken. –

+0

Trình tải * luôn * trông trong WinSxS trước nếu nó có đủ thông tin. Nó sẽ rơi trở lại địa phương tuy nhiên ngay cả khi có một publicKeyToken. –

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