dll调用,静态调用和动态调用的策略问题,请指教(100分)

  • 主题发起人 主题发起人 HanFeng
  • 开始时间 开始时间
H

HanFeng

Unregistered / Unconfirmed
GUEST, unregistred user!
我调用动态连接库时,一般都采用动态调用的方法,做法采用delphi帮助Dynamic Loading
的例子。但是,一日突发奇想,如果我把handle,以及被调用的函数和过程声明为全局变量,在
程序结尾才FreeLibrary,不必每次调用时都GetProcAddress,结果,每次调用,都会产生释放
不掉的内存。我应该怎样避免内存泄漏同时不用随时freelibrary呢?
此外,静态调用要好得多,但是,静态调用如何控制异常呢?我的动态连接库不存在的话,程序
直接退出了,有什么办法控制他呢?调用dll的模块是锦上添花的功能。
 
强烈关注! 我的问题与动态调用相关。

我你用动态调用资源文件作多国语言程序,当我调入资源后,现在的窗体位置被资源文件中
的覆盖了。怎么办?
 
我现在是用静态调用,当找不到动态连接库时程序退出就算了。
强列关注这个问题。
 
对于调用dll的模块是锦上添花的功能,建议还是动态调用好,一是不用的时候能够节省内存。
二是没有这东西的话也不影响系统整体功能。你的启动LoadLibrary,结束FreeLibrary,理论上应该是
可以的,不过看一下,是否存在多次调用的问题?
至于动态调用和静态调用,我的感觉是:如果动态库是系统的,如API,完全可以静态调用,
如果动态库是自己做的,且实时需要,没有就不能完成功能的,不妨也静态调用。
只有对于你说的锦上添花的功能或者很多时候用不到这个模块,此时才考虑动态调用。
 
yzhshi你好,我的程序大体结构如下:
var
h:hwnd;
func1:function(p1:....):....
function DynaLoading;
begin
if h<>0 exit;
h:=LoadLibrary('xx.dll')
...
func1:=getProcAddress(...)
end;

使用的时候,
procedure button1click...
begin
DynaLoading;
.....
end;

procedure button2click...
begin
FreeLibrary(h)
end;

procedure button3click
begin
//有可能是这里的问题:
AObject:=TAObject.create;
try
...
AObject.AMethod;//这个method中调用了func1
...
finaly

end;
.....
end;

 
老兄,你的DynaLoading所着Button的Click,执行了几次?
记住,没执行一次loadLibrary,必须有一个FreeLibrary与其相对应![:)]
 
yzhshi:
Button1和Button2都是一次,button3是多次,每次执行都有内存泄漏。
 
内存泄漏可能是我的测试方法不对。大家用什么方法测试呢?我是观察windows nt的任务
管理器猜测的。
 
采用动态调用DLL时,可以用全局方式,先将其放在申明UNIT中,在程序创建调用初始化,
结束时释放。
//DLL申明UNIT dllclear.pas
unit dllclear;

interface

uses
Windows, SysUtils, hydeclear, libcs;

type
Thyclient = Record
libload:Boolean;
connected:Boolean;
hyclient:THandle;
apSendstrToHost:TFarproc;
apConnectToHost:TFarproc;
apDisConnectToHost:TFarproc;
apNetWatchOption:TFarproc;
end;

type
TNetWatchOption = function ():boolean;
TSendstrToHost = function (sendstr:string):boolean;
TConnectToHost = function ():boolean;
TDisConnectToHost = function ():boolean;


Function HyClientInit:boolean;
Function HyClientDestroy:boolean;

var
hyclient:Thyclient;

implementation

Function HyClientInit:boolean;
begin
try
hyclient.hyclient:=Loadlibrary('hyclient.dll');
hyclient.apNetWatchOption:=GetprocAddress(hyclient.hyclient,'NetWatchOption');
hyclient.apSendstrToHost:=GetprocAddress(hyclient.hyclient,'SendstrToHost');
hyclient.apConnectToHost:=GetprocAddress(hyclient.hyclient,'ConnectToHost');
hyclient.apDisConnectToHost:=GetprocAddress(hyclient.hyclient,'DisConnectToHost');
if hyclient.hyclient>0 then
begin
hyclient.libload:=True;
Result:=True;
end
else
begin
hyclient.libload:=False;
hyclient.connected:=False;
Result:=False;
end;
except
Result:=False;
end;
end;

Function HyClientDestroy:boolean;
begin
try
FreeLibrary(hyclient.hyclient);
hyclient.libload:=False;
hyclient.connected:=False;
Result:=True;
except
Result:=False;
end;
end;

end.

主程序调用
procedure Form.OnCreate(Sender:TObject);
begin
if fileexists('hyclient.dll') then
begin
if not HyclientInit then
ShowError('网络监测库初始化失败!');
end;
end;

procedure Form.FormClose(Sender: TObject
var Action: TCloseAction);
begin
if hyclient.libload then
hyclientdestroy;
end;
 
接受答案了。内存泄漏可能是因为我的观测方法不当。
 
后退
顶部