標籤:
當使用了長字串類型的參數、變數時,如string,要引用ShareMem。
雖然Delphi中的string功能很強大,但若是您編寫的Dll檔案要供其它程式設計語言調用時,最好使用PChar類型。如果您要堅持使用string類型的參數時、變數甚至是記錄資訊時,就要引用ShareMem單元,而且這個單元必須是第一個引用的,即在uses語句後的第一個單元。
下面通過一個項目樣本來講解怎麼使用ShareMem。
先建立一個DLL項目
先建立一個DLL項目,然後再建立一個Unit1單元。
工程檔案是這樣的
library Project2;{ Important note about DLL memory management: ShareMem must be the first unit in your library‘s USES clause AND your project‘s (select Project-View Source) USES clause if your DLL exports any procedures or functions that pass strings as parameters or function results. This applies to all strings passed to and from your DLL--even those that are nested in records and classes. ShareMem is the interface unit to the BORLNDMM.DLL shared memory manager, which must be deployed along with your DLL. To avoid using BORLNDMM.DLL, pass string information using PChar or ShortString parameters. }uses ShareMem, SysUtils, Classes, Unit1 in ‘Unit1.pas‘;{$R *.res} exports test;beginend.
單元檔案裡面實現了test函數
unit Unit1;interface function test(const input: string): string; stdcall;implementation function test(input: string): string; stdcall; begin Result:= ‘我是DLL中的test函數,輸入是:‘ + input; end;end.
引入ShareMem的注意事項
1. 因為DLL中使用到string類型,所以一定要引入ShareMem單元。如果沒有用到string就不需要ShareMem,但是為了保險起見,還是建議引入ShareMem單元
2. 以這個項目為例,注意要在DLL的專案檔中引入ShareMem單元,而不是在函數的聲明和實現單元Unit1裡面引入ShareMem單元
3. 在專案檔中可能會引入很多單元,但是ShareMem單元一定要第一個引入,為了第一個載入
建立載入這個DLL的項目(產生可執行檔)
先建立一個項目,然後再建立一個Unit1單元。
上面的那個DLL的項目編譯產生了Project2.dll動態連結程式庫,將該動態連結程式庫檔案放到這個可執行項目的項目目錄下方便載入
專案檔的源碼是這樣的
program Project1;uses ShareMem, Forms, Unit1 in ‘Unit1.pas‘ {Form1};{$R *.res}begin Application.Initialize; Application.CreateForm(TForm1, Form1); Application.Run;end.
單元檔案的代碼是這樣的(這個單元檔案中主要是表單相關代碼)
unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;type TForm1 = class(TForm) btn1: TButton; procedure btn1Click(Sender: TObject); private { Private declarations } public { Public declarations } end;var Form1: TForm1;implementation{$R *.dfm}procedure TForm1.btn1Click(Sender: TObject);type TAddc= function(const input: string): string; stdcall;var hh: THandle; addc: TAddc;begin hh:= LoadLibrary(‘Project2.dll‘); try if hh<>0 then @addc:= GetProcAddress(hh, PChar(‘test‘)); if not (@addc = nil) then begin ShowMessage(addc(‘lsls‘)); end; finally FreeLibrary(hh); end;end;end.
這個可執行項目載入了上面的DLL,而上面的那個DLL裡面使用到了string,所以這個專案檔中也需要引入ShareMem單元。
但是也是有注意事項的:
1. 載入了使用string的DLL的項目也需要引入ShareMem。如果沒有用到string就不需要ShareMem,但是為了保險起見,還是建議引入ShareMem單元
2. 以這個項目為例,注意要在該可執行專案檔中引入ShareMem單元,而不是在函數的聲明和實現單元Unit1裡面引入ShareMem單元
3. 在專案檔中可能會引入很多單元,但是ShareMem單元一定要第一個引入,為了第一個載入
我在實驗時候出現的問題
因為我在可執行項目中引入ShareMem單元時候沒有注意到應該在專案檔而不是在單元檔案中引入,所以在編譯執行之後,可以正確運行,但是當關閉程式的時候卻報錯,如
報錯:不合法的指標。
將引入ShareMem單元的引入改到專案檔而不是在單元檔案中,然後問題就解決了。
Delphi在建立和使用DLL的時候如果使用到string,請引入ShareMem單元