2008-12-14 17 views
14

Tôi đang tìm cách thêm khả năng cho người dùng viết các plugin vào chương trình mà tôi đã phát triển ở Delphi. Chương trình này là một tập tin thực thi duy nhất không có DLL được sử dụng.Cách tốt nhất để thêm Khả năng của Plugin vào chương trình Delphi

Điều này sẽ cho phép cộng đồng người dùng viết tiện ích mở rộng cho chương trình của tôi để truy cập dữ liệu nội bộ và thêm các khả năng mà họ có thể thấy hữu ích.

Tôi đã xem bài đăng tại: Suggestions for Adding Plugin Capability? nhưng câu trả lời của nó dường như không thể chuyển sang chương trình Delphi.

Tôi muốn, nếu có thể, để thêm khả năng này và duy trì ứng dụng của tôi dưới dạng một tệp thực thi duy nhất mà không cần bất kỳ DLL hoặc mô-đun bổ sung nào.

Bạn có biết bất kỳ tài nguyên, thành phần hoặc bài viết nào đề xuất cách thực hiện tốt nhất trong Delphi hay bạn có đề xuất của riêng mình không?

+0

Xem thêm lời giải thích trong câu trả lời của tôi – Serguzest

Trả lời

10

Câu hỏi đầu tiên tôi sẽ hỏi là bạn có cần plugin để truy cập giao diện người dùng của ứng dụng máy chủ lưu trữ hay thêm bất kỳ phần tử giao diện người dùng nào của riêng mình không? Hoặc các plugin có bị giới hạn truy vấn và/hoặc cung cấp dữ liệu cho ứng dụng máy chủ của bạn không?

Cách thứ hai dễ dàng hơn nhiều và mở ra hai khả năng. Những người khác đã đề cập đến DLL, đó là cách đầu tiên để đi. Một số cảnh báo nhất định áp dụng - nói chung bạn nên giao tiếp với dll chỉ sử dụng các loại dữ liệu được sử dụng trong Windows API. Theo cách này, bạn có thể chắc chắn rằng các plugin DLL sẽ hiểu các kiểu dữ liệu của bạn, bất kể ngôn ngữ/trình biên dịch chúng được tạo ra. (Ví dụ, sử dụng PChars, chứ không phải các chuỗi. Không phải là quy tắc chuyển các lớp Delphi như TStream sang một DLL. Điều này sẽ xuất hiện để làm việc trong một số trường hợp, nhưng không an toàn nói chung, bởi vì ngay cả khi DLL được biên dịch trong Delphi, nó có thể là một phiên bản khác của trình biên dịch, với một ý tưởng hơi khác về TStream là gì). Google sử dụng các tệp DLL trong Delphi và bạn sẽ tìm thấy nhiều mẹo hơn.

Một cách khác chưa được đề cập đến là bật tính năng tạo tập lệnh trong ứng dụng của bạn. Có rất nhiều công cụ tạo kịch bản bên thứ ba rất có khả năng, cả thương mại và miễn phí, và hầu hết trong số chúng cho phép bạn trao đổi các đối tượng Delphi bằng kịch bản. Một số thư viện này chỉ hỗ trợ Pascal làm ngôn ngữ kịch bản, những thư viện khác sẽ cho phép bạn sử dụng Cơ bản (có lẽ tốt hơn cho người dùng mới bắt đầu) hoặc các ngôn ngữ khác. Xem ví dụ RemObjects Pascal Script (miễn phí) tại http://www.remobjects.com/free.aspx.

Giải pháp kịch bản yêu thích của tôi tại thời điểm này là Python cho Delphi (P4D, cũng miễn phí) từ http://mmm-experts.com/Products.aspx?ProductID=3 Nó có thể giao diện đẹp mắt với các lớp của bạn qua RTTI, và cho phép bạn thực thi mã Python trong ứng dụng Delphi của bạn, cũng như sử dụng Delphi các lớp trong các kịch bản Python. Do sự phổ biến của Python, đây có thể là một giải pháp khả thi nếu bạn muốn thu hút các nhà phát triển đến dự án của bạn. Tuy nhiên, mọi người dùng sẽ cần cài đặt bản phân phối Python.

Dường như với tôi rằng rào cản truy cập, từ quan điểm của các nhà văn plugin tiềm năng, thấp hơn nếu bạn sử dụng kịch bản hơn nếu bạn chọn các tệp DLL.

Bây giờ, quay lại câu hỏi ban đầu của tôi: mọi thứ trở nên phức tạp hơn nhiều nếu bạn cần plugin tương tác với giao diện người dùng của mình, ví dụ: bằng cách đặt các điều khiển trên đó. Nói chung, DLL không thể được sử dụng để làm điều này. Cách xử phạt Borland/CodeGear là sử dụng các gói (BPL). Với BPL, bạn có thể truy cập và khởi tạo các lớp được cung cấp bởi một plugin như thể chúng được khai báo trong ứng dụng máy chủ của bạn. Việc nắm bắt được, tất cả các BPL phải được biên dịch với cùng một phiên bản chính xác và xây dựng Delphi mà ứng dụng chính của bạn là. Theo tôi, điều này làm cho các gói hoàn toàn không thực tế, vì thật khó để mong đợi rằng tất cả các nhà văn tiềm năng trên toàn thế giới sẽ sử dụng cùng một phiên bản của Delphi mà bạn đang có. Một cạm bẫy lớn.

Để giải quyết vấn đề này, tôi đã thử nghiệm một cách tiếp cận khác: tiếp tục sử dụng DLL và phát triển cú pháp cho plugin để mô tả giao diện người dùng cần, sau đó tự tạo giao diện người dùng trong ứng dụng máy chủ. (XML là một cách thuận tiện để thể hiện giao diện người dùng, vì bạn có khái niệm về nuôi dạy con/làm tổ miễn phí.) Cú pháp mô tả giao diện người dùng có thể bao gồm gọi lại đến DLL được kích hoạt khi nội dung hoặc trạng thái của điều khiển thay đổi. Phương pháp này sẽ hạn chế các plugin cho tập hợp các điều khiển VCL mà ứng dụng của bạn đã sử dụng hoặc đã đăng ký. Và nó không phải là một công việc một-nighter, trong khi BPL chắc chắn là.

Google cho "khung plugin Delphi", quá. Có một số giải pháp làm sẵn, nhưng theo như tôi biết họ thường sử dụng BPL, với tính hữu dụng hạn chế của họ.

+0

+1. Rất nhiều lời khuyên rất tốt ở đây. Tạo một giao diện plug-in có rất nhiều hậu quả, trong một thời gian rất dài, do đó, suy nghĩ nhiều hơn về nó trước càng tốt. – mghie

1

Bạn có thể xem Hydra từ Nhắc nhở. Điều này không chỉ cho phép bạn thêm các plugin, mà còn để kết hợp win32 và .net.

2

Nếu plugin sẽ được phát triển trong trình tạo Delphi hoặc C++, hãy sử dụng gói + giao diện. Delphi OTA là một ví dụ tốt cho điều đó. Nếu plugin sẽ là ngôn ngữ độc lập, COM là một cách hay để thực hiện.

Ngoài ra: Nếu bạn không sử dụng COM, bạn có thể cần phải cung cấp SDK cho từng ngôn ngữ. Và việc xử lý dữ liệu giữa các ngôn ngữ khác nhau có thể gây đau (ví dụ như kiểu chuỗi delphi). Hỗ trợ Delphi COM là tuyệt vời, bạn không cần phải lo lắng về loại chi tiết. Đó là những người chủ yếu là impilicit với Delphi COM hỗ trợ. Đừng cố gắng phát minh ra bánh xe nữa. Tôi ngạc nhiên vì sao mọi người không có xu hướng đề cập đến nó.

+0

Tôi không quen thuộc với những gì Delphi OTA là, và một tìm kiếm Google ban đầu đã không giúp đỡ. Bạn có liên kết tốt với tài nguyên mô tả nó không? – lkessler

+0

Delphi OTA: API công cụ mở. Lần truy cập đầu tiên của Google: http://delphi.about.com/od/objectpascalide/a/wizardsexperts.htm –

+0

OTA = Mở công cụ api. Nó cung cấp nhiều giao diện để sử dụng các hàm của IDE trong một gói chuyên gia hoặc desingtime.Ví dụ, GExpert sử dụng rất nhiều hàm OTA. OTA không phải là loại hệ thống plugin chung cho các lập trình viên delphi. Đó là spesific để delphi IDE. Tôi nghĩ rằng nó có thể là một ví dụ tốt cho bạn. – Serguzest

9

Thực ra, the accepted answer to the question you cite cũng khá phù hợp với Delphi. Các trình cắm thêm của bạn sẽ là các tệp DLL và bạn có thể ra lệnh rằng chúng sẽ xuất một hàm có tên và chữ ký nhất định. Sau đó, chương trình của bạn sẽ tải DLL (với LoadLibrary) và nhận địa chỉ của hàm (với GetProcAddress). Nếu DLL không tải, hoặc chức năng không có, thì DLL không phải là một plug-in cho ứng dụng của bạn.

Sau khi bạn có địa chỉ cho DLL, bạn có thể gọi nó. Bạn có thể chuyển giao chức năng một giao diện cho một cái gì đó đại diện cho các phần của ứng dụng mà bạn muốn trưng ra. Bạn cũng có thể yêu cầu hàm trả về một giao diện với các phương thức mà ứng dụng của bạn sẽ gọi vào các thời điểm khác nhau.

Khi thử nghiệm hệ thống trình cắm của bạn, bạn nên tự mình viết một trình cắm bằng ngôn ngữ khác với ngôn ngữ Delphi. Bằng cách đó, bạn có thể tự tin hơn rằng bạn đã không vô tình yêu cầu tất cả mọi người sử dụng Delphi.

+1

+1 trên gợi ý rằng trình cắm phải được ghi bằng các ngôn ngữ khác ngoài Delphi. Nếu không nó đơn giản hơn rất nhiều để chỉ bao gồm RemObjects Pascal scripting vào ứng dụng của bạn và được thực hiện với nó. Việc tạo giao diện cho các đối tượng bên trong của bạn là cần thiết trong cả hai trường hợp, ... – mghie

+0

và với tập lệnh nội bộ, bạn không phải đầu tư thêm bất kỳ công việc nào cho giao diện trình cắm thêm. Ngoài ra, hãy đảm bảo rằng các trình cắm thêm có thể được kiểm tra, thêm và xóa mà không cần đóng ứng dụng của bạn. – mghie

+0

"Bạn có thể chuyển giao chức năng cho giao diện ..." Bạn có nghĩ các ngôn ngữ khác có thể sử dụng hoặc triển khai giao diện delphi không có COM không? – Serguzest

4

Tôi đang sử dụng plugin để thực hiện hầu hết các chức năng trong công cụ trò chơi mà tôi đang xây dựng. EXE chính được tạo thành từ một công cụ tập lệnh, trình quản lý trình cắm thêm, một số thường trình đồ họa cơ bản và không nhiều thứ khác. Tôi đang sử dụng TJvPluginManager từ thư viện VCL JEDI. Đó là một người quản lý rất tốt, và nó có thể thêm bất cứ thứ gì bạn muốn vào chương trình của bạn. Kiểm tra các bản trình diễn đi kèm với gói để xem nó hoạt động như thế nào. Nhược điểm duy nhất là nó thêm rất nhiều mã JCL/JVCL vào chương trình của bạn, nhưng đó không thực sự là vấn đề nếu bạn đã sử dụng các thành phần JVCL khác.

+0

TJvPluginManager có giới hạn các trình cắm thêm cho các trình cắm được viết bằng Delphi không? Giao diện được triển khai như thế nào, qua COM? – mghie

+2

Có, các plugin phải được viết bằng Delphi. (Hoặc có thể C++ Builder. Không chắc chắn.) Các plugin phải được hạ xuống từ lớp cơ sở TJvPlugin, về cơ bản chỉ là một trình bao bọc xung quanh chức năng plugin của bạn để cho phép nó nói chuyện với người quản lý. Và bạn có thể thực hiện nó như một DLL hoặc một BPL. –

6

Tôi đã cố gắng tạo một overview of all such options một số thời gian trước đây. Cùng với độc giả/người nhận xét của chúng tôi, chúng tôi đã tạo danh sách này:

  • DLL/BPL được tải từ chương trình.
  • DLL/BPL được tải từ một hộp cát (có thể là một bản sao khác của chương trình hoặc ứng dụng "máy chủ" chuyên dụng và liên lạc với chương trình chính qua thư/sockets/msmq/named pipes/mailslots/memory mapping files).
  • COM (trong bất kỳ biến thể nào của nó).
  • DDE (vui lòng không).
  • Chương trình bên ngoài giao tiếp thông qua đầu vào/đầu ra stanard.
  • Chương trình bên ngoài liên lạc qua tệp (tên tệp là tham số của chương trình).
  • Chương trình bên ngoài hoạt động qua thư mục thả (hữu ích để xử lý theo lô).
  • Chương trình bên ngoài giao tiếp với cửa sổ thư/cửa sổ ổ cắm/msmq/tên đường ống/mailslots/bộ nhớ ánh xạ tệp/cơ sở dữ liệu xuất bản-đăng ký.
4

Phương pháp phổ biến nhất để thêm khả năng plug-in là sử dụng COM. Một cuốn sách hay để bạn bắt đầu trên đường là Delphi Com Programming bởi Eric Harmon. Trong khi ban đầu nó được viết cho các phiên bản Delphi từ 3 đến 5, các nội dung sách vẫn còn hợp lệ với các phiên bản mới nhất của Delphi.

Cá nhân, tôi đã sử dụng kỹ thuật này cùng với kịch bản hoạt động để cho phép tùy chỉnh người dùng cuối.

7

Lúc đầu, tôi đã đi cho BPL và plugin cơ sở DLL. Và thấy họ khó khăn để duy trì.

Nếu bạn sử dụng hệ thống BPL, thì bạn cần phải phù hợp với phiên bản BPL với phiên bản EXE. Điều này bao gồm các bản cập nhật Delphi có thể phá vỡ một cái gì đó. Tôi phát hiện ra (một cách khó khăn) rằng nếu tôi cần phải bao gồm tất cả các plugin của tôi với mỗi bản phát hành, không có điểm nào trong việc có plugin.

Sau đó, tôi chuyển sang plugin DLL thuần túy. Nhưng hệ thống đó chỉ là mã cơ sở phức tạp. Và đó không phải là một điều tốt.

Trong khi cố mạng, tôi đã phát hiện ra Lua ngôn ngữ tập lệnh được nhúng và được phân phối cùng với ngôn ngữ đó. Lua là 150K DLL, nhúng trình biên dịch bytecode, thông dịch viên và ngôn ngữ lập trình động rất đơn giản và thông minh.

Plugin của tôi là các tập lệnh lua đơn giản. Dễ dàng mantaind và thực hiện. Có các ví dụ Delphi được tạo sẵn, vì vậy bạn có thể xuất bất kỳ lớp hoặc thủ tục nào làm bảng hoặc hàm Lua. GUI hay không. Ví dụ tôi đã có TurboPower Abbrevia trong ứng dụng của tôi để nén. Tôi đã xuất lớp nén của mình sang lua và tất cả các plugin hiện có thể gọi zip ('.', 'dir.zip') và giải nén(). Sau đó, tôi chuyển sang 7zip và chỉ thực hiện lớp cũ để sử dụng 7zip. Tất cả plugin đều hoạt động như chúng đã thực hiện, với hỗ trợ cho mã zip mới ('.', 'dir.7z').

Tôi đã thực hiện TLuaAction gọi thủ tục Execute(), Update(), Hint() từ tập lệnh của nó.

Lua allso có hệ thống plugin riêng của nó giúp dễ dàng thêm tính phù hợp vào nó. Ví dụ: luacom make là dễ sử dụng tự động hóa COM, luainterface cho phép gọi .net từ lua. Xem luaforge để biết thêm. Có Lua IDE được thực hiện tại Delphi, với nguồn.

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