淺述如何為程式提供二次開發功能 1 原創

2021-04-01 23:43:17 字數 2871 閱讀 7714

什麼是二次開發?    我自己理解為:使用者可以利用提供者提供的介面使用已有系統中的資源、功能為已有系統提供新的功能;而所提供的新功能可以無縫整合到已有系統中,已有系統無需重新編譯。

為系統提供二次開發功能,以前覺得是比較神秘的東西,但是自從去年仔細捉摸一番後,發現事實沒有那麼難,我就把曾經的經歷寫出來給大家看看.

提到二次開發,我不知道大家首先想的是什麼軟體,我想到的是autocad,比較熟悉它的vba二次開發,不過拿起objectarx也玩得轉.我所說的這套二次開發的思路與objectarx比較相像,都是用動態鏈結庫實現;現在跟我一步一步的探索吧,不過還要多動腦筋,免得陷入我的思維定勢;那樣我的拋磚引玉的想法就泡湯啦,會比較失望:(,now let's begin.

1.1 動態鏈結庫

動態鏈結庫的簡單例子

library mydll;

uses

sysutils,

classes,

dialogs;

procedure test(str: pchar); export; stdcall;

begin

showmessage(str);

end;

exports test;

begin

end.

上面是乙個完整的動態鏈結庫**,下面是呼叫方法

type

tdllfunc = procedure(str: pchar); stdcall;

vardllhandle: thandle;

dllfunc: tdllfunc;

...dllhandle := loadlibrary('mydll.dll');

...dllfunc := getprocaddress(dllhandle, 'test');

dllfunc('測試我的動態鏈結庫');

...freelibrary(dllhanle);

關於動態鏈結庫就到這,不再贅述了

1.2 動態鏈結庫的統一介面

有了動態鏈結庫,我們的程式可以實現擴充了;但是問題又來了,我們的程式怎麼知道動態鏈結庫中的函式名字、引數等?不知道怎麼呼叫?其實解決這個問題有乙個很簡單地做法---那就是統一函式名稱和引數;這樣,我們的程式只需要找到動態鏈結庫檔案就可以呼叫它們了;現在我們把編譯好的動態鏈結庫放到指定的目錄,這樣我們的exe可以到這個目錄中遍歷所有的.dll檔案,從而呼叫它們提工的功能函式。

下面是我以前的**中的一部分(載入目中的全部.dll檔案,以及得到它們的功能藉口)

procedure tdllmanager.getworkers;

varsrec: tsearchrec;

retval: integer;

dllfunc: tdllfunc;

begin

// 在當前目錄下的dev2目錄中搜尋*.dll檔案

retval := findfirst('./dev2/*.dll', faanyfile, srec); 

trywhile retval = 0 do

begin

if (srec.attr and fadirectory) = 0 then  // 檔案

begin

// 載入動態連線庫

trytmpdllname := srec.name;

tmphandle := loadlibrary(pchar('./input/' + tmpdllname));   // 載入動態鏈結庫

dllfunc := getprocaddress(tmphandle, dllfuncname);          // 取得函式位址

if assigned(dllfunc) then

dllfunc();        // 呼叫函式

except

if tmphandle <> 0 then

freelibrary(tmphandle);

end;

end;

retval := findnext(srec);

end;

finally

findclose(srec);

end;

end;

好了,現在程式怎麼自動呼叫動態鏈結庫的方法有了(其實是變通了一下而已)。

1.3 在動態鏈結庫中呼叫exe中的函式

現在,我想為主程式新增乙個新的選單,怎麼辦?把mainmenu作為引數傳給動態鏈結庫,對這種做法確實可行,但是又沒有考慮過,如果我的二次開發工作是在vc中進行的,怎麼辦?vc中可沒有delphi的tmainmenu控制項。

想想window api中的的視窗**,我們會不會有啟發呢?對,**函式可以解決上面的問題。

下面用**簡單說明:

type

procedure tcallback = procedure(menuname: pchar); stdcall;

// 注意這個函式一定不要是類的成員函式

procedure addmenu(menuname: pchar);

begin

// 新增選單

... ...

end;

呼叫動態鏈結庫

type

procedure tdllfunc(callbacl: tcallback); stdcall;       

... ...

vardllfunc: tdllfunc;

// 載入dll,取得函式位址

...dllfunc(tcallback(addmenu));

...動態鏈結庫中這樣寫     

procedure test(callbacl: tcallback); stdcall; export;

begin

callback('測試選單');  // **函式,實現新增選單

end;

openstf二次開發免登入功能

openstf已經很流行了現在有個需求,需要把openstf介入到現有系統中,直接跳轉到裝置管理頁面,話不多說,直接上 var log logger.createlogger auth mock log.setlocalidentifier req.ip switch req.accepts jso...

UEditor如何進行二次開發

ueditor 雖然功能眾多,但對於廣大開發者來說,還是有很多定製化的功能需求,如果都靠ueditor團隊自己開發那是不現實的,這時就需要廣大開發者在ueditor的基礎上自己開發定製功能。但在之前的版本中,ueditor對於二次開發的支援不夠優化,經常需要開發者不僅要開發相應的功能,例如comma...

如何用Qt做SolidWorks二次開發

這個問題困擾了我2年了,之前找到的教程都是mfc的,atl匯入嚮導或是通過匯入型別庫的方式來呼叫控制項,我一直都搞不明白。最近學習了activeqt以及通過activeqt控制excel word powerpoint flash後,我終於大致明白了。首先我要說明白一下,vc都是通過com來操作so...