vb调用dll:dll的创建与调用



tiDLL参数约定
——————————————————————
令传递顺序参数删除
stdcall从左到右方面
cdecl从右到左方面
pascal从左到右方面
register从左到右方面
━━━━━━━━━━━━━━━━━━━━━━
退出过程编译时必须关闭stack_checking因而需设置编译指示{$S-} 
━━━━━━━━━━━━━━━━━━━━━
//——————————dll创建
brarymydll
{$S-}
//————————uses单元
uses
es,stdsys,foRMin’form.pas’{form};
//—————————变量声明
var
love:;
baby:eger;
SaveExit:Poer; 
//—————————和过程
proceduremyinnerproc;stdcall;//内部使用过程
begin
{添入代码}
end;
proceduremyproc(varlove:);stdcall;export;//输出可以过程
begin
{添入代码}
end;
functionmyfunction(baby:eger):eger;stdcall;export;//可
begin
{添入代码}
end;
procedureLibExit;far;
begin
ExitCode=wep__Exitthen
begin
{系统关闭时相应处理}
end

begin
{DLL卸出时相应处理}
end;
ExitProc:=SaveExit;{恢复原来退出过程指针}
end; 
//——————————输出介绍说明
exports
myprocname’myproc’index1,
myfunctionname’myfuntion’index2risdent;//输出信息始终保持在内存中{risdent}
//——————————化工作
begin
{DLL化工作}
SaveExit:=ExitProc;{保存原来退出过程指针}
ExitProc:=@LibExit;{安装新退出过程}
End.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
XML:prefix=ons=\"urn:schemas-microsoft-com:Office:office\"/>
表10.1ExitCode取值和意义:取值意义
—————————————————————
WEP__Exitwindows关闭 
WEP_Free_DLLxDLLs被卸出
━━━━━━━━━━━━━━━━━━━━━ 
//--------------dll
1静态
 在静态个DLLs中过程或external指示增加到过程或声明语句中
过程或必须采用远模式这可以使用far过程指示或个{$F+}编译指示 [Page]
Delphi全部支持传统Windows动态链接库编程中 3种方式它们是:
  ●通过过程/
  ●通过过程/别名
  ●通过过程/顺序号 
//————————————————————静态举例
unitwindows
erface
functionFindWindowsEx(Parent,Child:hwnd;name,windowsname:pchar):hwnd;stdcall;
const
user32=’user32.dll’
implementation
functionFindWindowEx;externaluser32name’FindWindowExA’
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
2.动态 
2.1动态api 
  动态中使用WindowsAPI主要有 3个,即:LoadlibraryGetProcAddress和Freelibrary
1.Loadlibrary:把指定库模块装入内存
  语法为:  functionLoadlibrary(LibFileName:PChar):THandle; 
LibFileName指定了要装载DLLs文件名如果LibFileName没有包含个路径则Windows按下述顺序进行查找:
 (1)当前目录;
 (2)Windows目录(包含win.com目录)GetWindowDirectory返回这目录路径;
 (3)Windows系统目录(包含系统文件如gdi.exe目录)GetDirectory返回这目录路径;
 (4)包含当前任务可执行文件目录利用GetModuleFileName可以返回这目录路径;
 (5)列在PATH环境变量中目录;
 (6)网络映象目录列表
  如果执行成功则返回装载库模块例子句柄否则返回个小于HINSTANCE_ERROR代码代码意义如下表: 
表10.2Loadlibrary返回代码意义
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
代码         意        义
——————————————————————————————————————
0系统内存不够可执行文件被破坏或非法
2文件没有被发现
3路径没有被发现
5企图动态链接个任务或者有个共享或网络保护错
6库需要为每个任务建立分离数据段
8没有足够内存启动应用
10Windows版本不正确
11可执行文件非法或者不是Windows应用或者在.EXE映像中有
12应用个区别操作系统设计(如OS/2)


13应用为MSDOS4.0设计
14可执行文件类型不知道
15试图装载个实模式应用(为早期Windows版本设计)
16试图装载包含可写多个数据段可执行文件第 2个例子
19试图装载个压缩可执行文件文件必须被解压后才能被装裁
20动态链接库文件非法 [Page]
21应用需要32位扩展
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
假如在应用用Loadlibrary模块前其它应用已把该模块装入内存则Loadlibrary并不会装载该模块例子而是使该模块“引用计数”加1 
2.GetProcAddress:捡取给定模块中地址
 语法为:  functionGetProcAddress(Module:THandle;ProcName:PChar):TFARProc; 
Module包含被库模块句柄这个值由Loadlibrary返回如果把Module设置为nil则表示要引用当前模块
 ProcName是指向含有以nil结尾指针或者也可以是次序值如果ProcName参数是次序值则如果该次序值在模块中并不存在时GetProcAddress仍返回个非nil这将引起混乱因此大部分情况下用名是种更好选择如果用拼写必须和动态链接库文件EXPORTS节中对应拼写相
如果GetProcAddress执行成功则返回模块中入口处地址否则返回nil
3.Freelibrary:从内存中移出库模块
  语法为: procedureFreelibrary(Module:THandle); 
Module为库模块句柄这个值由Loadlibrary返回
  由于库模块在内存中只装载因而Freelibrary首先使库模块引用计数减如果引用计数减为0则卸出该模块
 每次Loadlibrary就应次FreeLibray以保证不会有多余库模块在应用结束后仍留在内存中www.  
//————————————动态举例 
 在利用GetProcAddess返回指针时必须进行强制类型转换: 
Order:=TInstr(PFunc)(text,Key);
 TInStr是个定义好了类型: 
type
TInStr=function(source:PChar;Check:Char):Integer;
//---------------------------------
procedureTForm1.Edit2KeyPress(Sender:Tobject;varKey:Char);
var
order:Integer;
txt:PChar;
PFunc:TFarProc;
Moudle:THandle;
begin
Moudle:=Loadlibrary(’c:dllsexample.dll’);
Moudle>32then
begin
Edit2.text:=’’;
Pfunc:=GetProcAddress(Moudle,’Instr’);
txt:=StrAlloc(80);
txt:=StrPCopy(txt,Edit1.text);
Order:=TInstr(PFunc)(txt,Key);
Order=-1then
Label1.Caption:=’不包含这个
end
Label1.Caption:=’位于第’+IntToStr(Order+1)+’位’; [Page]
Freelibrary(Moudle);
end;

//————————————用于实现数据传输DLLs编写 

用于实现数据传输DLLs和般DLLs编写基本相同其中特别地方是:
1.定义个全局变量句柄: 
var
hMem:THandle;
2.定义个过程返回该全局变量句柄该过程要包含在exports子句中如: 
functionGetGlobalMem:THandle;export;
begin
Result:=hMem;
end;
3.在化代码中分配全局内存块:
清单如下: 
begin
hMem:=GlobalAlloc(gmem_MOVEABLEandgmem_DDEShare,num);
hMem=0then
MessageDlg(’Couldnotallocatememory’,mtWarning,[mbOK],0);
end.
//————————————————————————————————
 num是个预定义常数
表10.3全局内存块分配标志:标志意义
—————————————————————————————————
gmem_DDEShare分配可由应用共享内存
gmem_Discardable分配可抛弃内存(只和gmem_Moveable连用)
gmem_Fixed分配固定内存
gmem_Moveable分配可移动内存
gmem_Nocompact该全局堆中内存不能被压缩或抛弃
gmem_Nodiscard该全局堆中内存不能被抛弃
gmem_NOT_Banked分配不能被分段内存
gmem_Noty通知功能当该内存被抛弃时GlobalNoty
gmem_Zeroinit将所分配内存块内容化为零
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 
有两个预定义常用组合是:
GHND=gmem_Moveableandgmem_Zeroinit
GPTK=gmem_Fixedandgmem_Zeroinit
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 
Tags:  调用dll vc调用dll java调用dll vb调用dll

延伸阅读

最新评论

发表评论