我写了个Dll,为了看Delphi写的DLL是否稳定,我是循环来测试,连续执行1000次,结果不到50次就会报错,然后我在调用Dll的单元中加上 ShareMem 单元,结果非常稳定,但是我关闭程序的时候就会报错!!!不知道为什么?后来我新建一个应用程序,在一个空白的窗体单元加上 ShareMem 单元,
然后我啥也不干,运行程序,结果退出时报错!!!服了,难道 ShareMem 单元不能用?不信的话你可以新建一个应用程序,然后在unit1的首位置加上 ShareMem 单元,然后运行程序,关闭,看报错不?我用的D7就是报错!!!
然后我啥也不干,运行程序,结果退出时报错!!!服了,难道 ShareMem 单元不能用?不信的话你可以新建一个应用程序,然后在unit1的首位置加上 ShareMem 单元,然后运行程序,关闭,看报错不?我用的D7就是报错!!!
但是在dll与application之间,很有可能你application里的一个string内存在dll中被释放了,那么再到application去的时候,就会报错。
所以必须加sharemem协调string管理机制!On Windows, if a DLL exports routines that pass long strings or dynamic arrays as parameters or function results (whether directly or nested in records or objects), then the DLL and its client applications (or DLLs) must all use the ShareMem unit. The same is true if one application or DLL allocates memory with New or GetMem which is deallocated by a call to
Dispose or FreeMem in another module. ShareMem should always be the first unit listed in any program or library uses clause where it occurs.ShareMem is the interface unit for the BORLANDMM.DLL memory manager, which allows modules to share dynamically allocated memory. BORLANDMM.DLL must be deployed with applications and DLLs that use ShareMem. When an application or DLL uses ShareMem, its memory manager is replaced by the memory manager in BORLANDMM.DLL.
但我搜遍整个电脑,就是找不到那个DLL,是不是帮助文档年代太久了,没更新!!
注意没有什么静态 link 一说, 必须同时
一般在C:\Program Files\Borland\Delphi7\Bin
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
SysUtils,
adodb,
Windows,
Classes;var
Qry : TADOQuery;{$R *.res}procedure InitDll(ConStr:Pchar);stdcall;
begin
Qry := TADOQuery.Create(nil);
Qry.ConnectionString := ConStr;
end;function QueryDll(TableName,ID:pchar):Pchar;stdcall;
var
i: integer;
s: String;
h: HWND;
begin
s := '';
Result := Pchar(s);
h := GetForeGroundWindow();
// MessageBox(h,PChar(Qry.ConnectionString),'dll',MB_OK or MB_ICONINFORMATION);
try
with Qry do
begin
CLose;
SQL.Text := Format('select * from %s where id = %s ',[TableName,ID]);
Open;
end;
if Qry.IsEmpty then
begin
Exit;
end;
for i := 0 to Qry.FieldCount - 1 do
begin
if i = 0 then
s := Qry.Fields[0].AsString
else
s := s + '#'+ Qry.Fields[i].AsString;
end;
except
end;
Result := Pchar(s);
end;procedure CloseDll() ;stdcall;
var
h: HWND;
begin
h := GetForeGroundWindow();
MessageBox(h,'CloseDll','dll',MB_OK or MB_ICONINFORMATION);
if assigned(Qry) then
begin
Qry.Free;
Qry := nil;
end;
end;
exports
CloseDll,
QueryDll,
InitDll;
end.
var
i: integer;
p: Pchar;
begin
for i := 1 to 1000 do
begin
p := QueryDll(Pchar(edit1.Text),Pchar(inttostr(i)));
Memo1.Lines.Add(p);
application.ProcessMessages;
Button4.Caption := inttostr(i);
end;
ShowMessage('ok');
end;