2015-08-17 19 views
26

Dự án của tôi (một số loại động cơ xử lý) được chia thành 2 dll: một với khai báo giao diện và một với chức năng. Thường thì dự án được sử dụng bởi dự án Delphi bên ngoài thông qua công nghệ COM.Làm thế nào để làm cho dll của tôi có thể tải từ codebase chỉ?

Cho phép nói rằng chương trình của tôi cắt trái cây. Chương trình Delphi bên ngoài tạo đối tượng Fruit và điền vào các thuộc tính của nó: weight (int), Name (string) và ProgressUpdater (thuộc loại IProgressUpdater được khai báo trong dll thứ hai với các giao diện) .Sau đó, người tạo trình tạo slicer, tạo Slicer.AddFruit (newFruit) và gọi Slicer.Slice().

Không có gì đặc biệt. Trong dự án delphi đời thực là addin Outlook. Nhưng đây là vấn đề - đôi khi một số addins VSTO làm cho Outlook hoạt động trong chế độ "shadow copy files", vì vậy khi dự án delphi bắt đầu và tạo đối tượng Slicer, assembly C# của chúng ta sẽ được đặt trong thư mục temp và assembly sẽ được tạo với đường dẫn cục bộ này. Vâng ... đây vẫn không phải là một vấn đề. Nhưng vấn đề là khi dự án delphi tạo ra newFruit và sau đó vượt qua đối tượng ProgressUpdater, trong assembly Slicer của tôi, tôi không thể lấy ProgressUpdater bên ngoài: "Đối số trả về có loại không hợp lệ", nhưng vẫn có thể lấy trường với các kiểu đơn giản (Weight, Name).

Điều này chỉ xảy ra khi chế độ shadowCopyFiles bật. Vì vậy, tôi đoán là - lắp ráp bên ngoài ProgressUpdater và lắp ráp Slicer được đặt ở những nơi khác nhau, vì vậy họ không thể được thông qua. Câu hỏi của tôi là làm thế nào để tránh dll của tôi được "bóng sao chép"? Hoặc là có một số giải pháp khác nhau?

+1

Tôi không phải là rất familliar với công nghệ COM, nhưng không nên hội đồng được lấy từ GAC? Giống như [ở đây] (http://edn.embarcadero.com/article/32754) – netaholic

+1

Hmm, bạn là nạn nhân của một thực tiễn có vấn đề của người khác. Bạn không thể làm gì nhiều nếu bạn không có số điện thoại. Nhưng một điều, sử dụng GAC. Luôn luôn là một ý tưởng tốt khi bạn viết hội đồng ComVisible. –

+0

@HansPassant vấn đề là lắp ráp của tôi đã được đăng ký trong GAC. Nhưng trong một trường hợp Assembly.GetExecutingAssembly(). cho thấy đường dẫn codebase (đường dẫn mà nó được đăng ký với regasm cho COM interop). nhưng trong một (sau đó bổ sung VSTO) - một số đường dẫn tạm thời trên ổ đĩa hệ thống. Tôi nghĩ rằng tôi sẽ không có vấn đề như vậy nếu tôi có thể buộc. Net để tải lắp ráp của tôi chỉ từ con đường codebase. – Shelest

Trả lời

1

Do đó, tôi vẫn không có câu trả lời cho câu hỏi chính xác. Nhưng vấn đề được giải quyết (nhờ HansPassant) bằng cách sử dụng GAC, bởi vì các assembly tại GAC sẽ không bao giờ được sao chép (thực sự là linker sẽ luôn dò tìm các assembly trong GAC và sau đó ở các nơi khác).

Câu trả lời có thể cho câu hỏi là đi currentDomain.AssemblyResolve, nhưng tôi không thể áp dụng giải pháp này cho dll chứa giao diện công cộng (loại) chỉ. Có lẽ nó sẽ là giải pháp phù hợp cho một số trường hợp.

1

Bạn có thể sử dụng phản chiếu để tải DLL động từ bất kỳ vị trí nào bạn muốn. Nếu bạn có thể đi theo cách này, tôi có thể cung cấp thêm mã để tải DLL.

+0

Có, xin cung cấp một ví dụ. Tình hình của tôi là dll của tôi chỉ chứa các giao diện (không có phương thức nào) và sẽ được Delphi sử dụng thông qua COM. Vì vậy, làm thế nào tôi có thể đảm bảo rằng khi anh chàng trên Delphi kết thúc thực hiện MyComDll.IProgressUpdater nó sẽ được tải từ codebase? – Shelest

+0

@Shelest để tải lắp ráp thông qua phản ánh bạn có thể làm một cái gì đó như thế này: Assembly.Load (File.ReadAllBytes (đường dẫn)) - chỉ một lần trước khi cuộc gọi đầu tiên. Bạn cũng có thể xem bài viết của tôi: http://wojciechkulik.pl/csharp/embedded-class-libraries-dll (đó là về một cái gì đó khác, nhưng có lẽ một số phần của nó sẽ hữu ích). –

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