关于Delphi DLL动态连接库编写与调用的问题

loveddwd 2007-11-12 07:46:36
小弟学D有段时间了,虽然说现在能写一些简单的程序但是对DLL还是很陌生.看了许多关于DLL的文章对其有了一点初步的了解.但是编写与调用还是很模糊.

我的问题如下.

例如说我现在想写一个简单的加密算法的DLL.可是怎么编写怎么掉用就很模糊了.

加秘算法:

procedure TMain.SpeedButton1Click(Sender: TObject);
var
s1, s2, s3: string;
j: integer;
begin
if jm1 <> '' then
begin
s1 := jm1;
for j := 1 to length(s1) do
s1[j] := chr(ord(s1[j]) xor 255);
SetLength(s2, Length(s1) * 2);
BinToHex(PChar(s1), PChar(s2), Length(s1));
s3 := s2;
for j := 1 to length(s3) do
s3[j] := chr(ord(s3[j]) + 211);
jm := s3;
end;
end;


解密算法:

procedure TMain.SpeedButton2Click(Sender: TObject);
var
s1, s2, s3: string;
j: integer;
begin
if qm1 <> '' then
begin
s3 := qm1;
for j := 1 to length(s3) do
s3[j] := chr(ord(s3[j]) - 211);
s1 := s3;
SetLength(s2, Length(s1) div 2);
HexToBin(PChar(s1), PChar(s2), Length(s1));
for j := 1 to length(s2) do
s2[j] := chr(ord(s2[j]) xor 255);
qm := s2;
end;
end;


这是两个过程,我想写在一个DLL里,让程序能够掉用.但是怎么写怎么掉用我很模糊
意思就是说我想让程序的一个变量得到一个值后执行一次DLL的加秘算法然后把结果附给另外一个程序变量
需要解密的时候把这个加好密的变量再附给另外一个程序变量执行一次DLL的解密算法结果给程序的一个变量

程序变量 a:= '111' 然后让DLL的加密算法把'111'进行加密结果附给程序变量 b:= 'DLL加密结果'

程序变量 c:= '加密后的结果' 执行一次DLL的解密算法,把解密后的结果附给程序变量 d:= 'DLL解密结果'

现在的问题就是怎么在DLL里写这两个加密与解密算法.然后怎么让程序调用加密与解密.


各位大哥大姐,帮帮小弟.对DLL还是很模糊.呵呵感谢大家的帮助
...全文
299 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
loveddwd 2007-11-15
  • 打赏
  • 举报
回复
感谢三楼的大哥帮忙,呵呵,我主要是对动态连接库的概念很模糊所以怎么都转不过来.五楼的给的答案我在BAIDU里能查到一大堆的.所以给多少,一楼的大哥你的答案让我很头疼所以也没个几分

感谢大家的帮助
yiyi0518 2007-11-15
  • 打赏
  • 举报
回复
楼上的几位都讲那么仔细了, 楼主应该看得明白啦。。。
ideation_shang 2007-11-14
  • 打赏
  • 举报
回复
string 用pchar,记得uses ShareMem
liuyangsl 2007-11-14
  • 打赏
  • 举报
回复
注意delphi写的dll中尽量不要使用string类型
改用shortstring或者pchar
Sunniness 2007-11-13
  • 打赏
  • 举报
回复
呵呵,传指针,定义出口
feizhoutufei 2007-11-13
  • 打赏
  • 举报
回复
路过学习
大大怪老张 2007-11-13
  • 打赏
  • 举报
回复
都说了,纯接分
laowang2 2007-11-13
  • 打赏
  • 举报
回复
delphi调用DLL需要定义回调函数以确定DLL中函数的地址.
edongxu 2007-11-12
  • 打赏
  • 举报
回复
哈哈,str是形参,接受你的程序变量 a:= '111 '啊,
你啊,还是继续深入学习啊,参考:
动态链接库是一个能够被应用程序和其它的DLL调用的过程和函数的集合体,它里面包含的是公共代码或资源。由于DLL代码使用了内存共享技术,在某些地方windows也给了DLL一些更高的权限,因而DLL中可以实现一些一般程序所不能实现的功能,如实现windows的HOOK、ISAPI等。同时,DLL还为不同语言间代码共享提供了一条方便的途径。因而DLL在编程时应用较为广泛,本文将介绍如何在 Delphi 中建立和使用DLL。
一.DLL 库内存共享机制
从使用效果看,DLL和unit 很像,它们都可以被别的工程模块所调用,但二者在内部的实现机制上确存在着差别。如果一个程序模块中用uses语句引用了某个unit,编译程序在编译该模块时,便会连同unit一起编译,并把编译后的可执行代码链接到本程序模块中,这就是一个程序模块能够调用所引用unit中过程和函数的原因。当同一个unit被多个工程所引用时,则每个工程中都含有该unit的可执行代码,当含有该unit的多个工程同时执行时,unit的可执行代码会随不同工程而多次被调入内存,造成内存资源的浪费。DLL则不同,它即使被某个工程调用,编译后仍是独立的,也就是说编译后,一个DLL库形成一个单独的可执行文件,而不与任何其它的可执行文件连接在一起,因而DLL库并不从属于某个特定的工程,当多个工程调用同一个DLL库时只有第一个工程把DLL库调入内存,其余工程并不重复调入同一个DLL库到内存,而是到同一个共享内存区读取。并且,DLL的执行代码是在程序运行期间动态调入的,而不是如unit在程序运行时就与整个工程一起调入内存。这样便可消除unit带来的相同代码多处占用内存的弊病。
二 Delphi中DLL库的建立
在Delphi环境中,编写一个DLL同编写一个一般的应用程序并没有太大的区别。事实上作为DLL主体的DLL函数的编写,除了在内存、资源的管理上有所不同外,并不需要其它特别的手段。
一般工程文件的格式为:
program 工程标题;
uses 子句;
程序体
而DLLs工程文件的格式为:
library 工程标题;
uses 子句;
exprots 子句;
程序体
它们主要的区别有两点:
1.一般工程文件的头标用program关键字,而DLL工程文件头标用library 关键字。不同的关键字通知编译器生成不同的可执行文件。用program关键字生成的是.exe文件,而用library关键字生成的是.dll文件;
2.假如DLL要输出供其它应用程序使用的函数或过程,则必须将这些函数或过程列在exports子句中。而这些函数或过程本身必须用export编译指令进行编译。
在Delphi主菜单file 中选new...项,在弹出的窗口中双击DLL图标,便会自动给出DLL源模块框架,如下:
Library project1;
{...注释...}
uses
SysUtils, Classes;
begin
end.
接下来便可在USES和begin之间加入想在该DLL中实现的过程和函数的定义,并用export和exprots保字把它们引出,以便别的模块引用,在begin和end之间加入初始化代码,初始化代码是用来对DLL变量初始化的。应注意,即便无初始化代码begin与end也不可省略,如下例:
library minmax;
function Min(X, Y: Integer): Integer; export;
begin
if X < Y then Min := X else Min := Y;
end;
function Max(X, Y: Integer): Integer; export;
begin
if X > Y then Max := X else Max := Y;
end;
exports
Min index 1,
Max index 2;
begin
end.
经编译后,并以minmax.DLL存盘后,一个DLL库文件便形成了。
三 DLL库的访问
访问DLL库有两种方式,一种是静态引用,另一种是动态引用。
用静态引用这种方法装入DLL要做两件事情:为DLL 库创建一个输入单元,以及用USES把输入单元连接到要使用DLL 函数的程序模块中。为DLL库创建的输入单元与普通的单元的区别仅在于:在它的接口处声明的过程、函数,并不在它的实现部分给出真正的实现代码,而是用external关键字把过程、函数的实现细节委托给外部DLL模块。
external命令的使用语法如下:
procedure /function 过程/函数名;external DLL模块名;
下面给出为上面创建的minmax.DLL库写的输入单元源文件testdll .pas,从中可看出输入单元与一般单元的一些差别,代码如下所示:
unit testdll;
interface
uses
function Min (X, Y: Integer): Integer;
function Max (X, Y: Integer): Integer;
implementation
function Min; external ‘minmax.DLL’;
function Max; external ‘minmax.DLL’;
end.
一个应用程序若想调用minmax.DLL中的函数,只须在其uses语句中加入testdll 单元即可。
动态装入DLL,要用到Windows的三个API函数。Loadlibrary、Freelibrary和GetprocAddress 。loadlibrary函数用来装入DLL库,其调用格式如下:
function loadlobrary (DLLfileName:Pchar): THandle:
当不再需要一个DLL库时,应调用FreeLibrary函数将其释放,以空出宝贵的内存资源,其调用格式如下:
procedure FreeLibrary (Libmodule:THandle)
Libmodule 为由LoadLibrary调用得到的DLL库句柄。在用loadlobrary 函数装入某个DLL库和调用FreeLibrary释放该DLL库之间的程序段中, 可以使用该DLL库中的过程和函数,具体使用方法是:用GetprocAddress函数把DLL库中函数的地址传递给程序中某个函数变量,再用该变量实现DLL函数的调用。GetprocAddress函数声名如下,
function GetprocAddress (Libmodule:THandle:procname:pchar):TFarProc:
如下例所示:
type
TTimeRec = record
Second: Integer;
Minute: Integer;
Hour: Integer;
end;
TGetTime = procedure(var Time: TTimeRec);
THandle = Integer;
var
Time: TTimeRec;
Handle: THandle;
GetTime: TGetTime;
...
begin
Handle := LoadLibrary('DATETIME.DLL');
if Handle <> 0 then
begin
@GetTime := GetProcAddress(Handle, 'GetTime');
if @GetTime <> nil then
begin
GetTime(Time);
with Time do
WriteLn('The time is ', Hour, ':', Minute, ':', Second);
end;
FreeLibrary(Handle);
end;
end;
在调用动态链接库时应注意, 所需动态链接库须与应用程序在同一目录或Windows System 目录下。
动态链接库是 Windows下程序组织的一种重要方式,使用动态链接库可以极大地保护用户在不同开发工具、不同时期所做的工作,提高编程效率。
禹爸爸 2007-11-12
  • 打赏
  • 举报
回复
上面的if LibHandle = 0 then 要改成if LibHandle <> 0 then
禹爸爸 2007-11-12
  • 打赏
  • 举报
回复
新建一个DLL工程先,再工程中新建一个单元文件,在该文件中声明并实现你的加密与解密方法,在DLL中对字符串操作时,尽量使用PChar
unit Unit1;

interface

function encrypt(Str: PChar): PChar;
function decrypt(Str: PChar): PChar;

implementation

function encrypt(Str: PChar): PChar;
begin
//your code
end;

function decrypt(Str: PChar): PChar;
begin
//your code
end;

end.

然后在你的DLL工程中输出这两个方法
library Project1;

{ 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
SysUtils,
Classes,
Unit1 in 'Unit1.pas';

{$R *.res}

Exports
encrypt;
decrypt;

begin
end.


调用代码如下:
type
TMyFun = function (Str: PChar): PChar

procedure TForm1.Test;
var
s: String;
P: PChar;
MyFun: TMyFun;
LibHandle: THandle;
begin
s := 'adfadfafd';
LibHandle := LoadLibrary(DLLFileName);//你编译后的DLL所在的路径
try
if LibHandle = 0 then begin

MyFun := GetProcAddress(LibHandle, 'encrypt');
if Assigned(MyFun) then
MyFun(PChar(s));
finally
FreeLibrary(LibHandle);
end;
end;


loveddwd 2007-11-12
  • 打赏
  • 举报
回复
你写的我不明白啊.

首先你的函数里STR这个变量我不明白

而且函数的过程怎么写.

函数返回值等于jm,好模糊

能给我个方法吗?感谢您
edongxu 2007-11-12
  • 打赏
  • 举报
回复
做成dll文件想你上面定义函数可不行啊,不要放在事件里
变成函数,有返回值的,这样
function TestDll(str:string):string;stdcall;
begin
//////////////
Result:=jm;
end;


exports TestDll;


调用:
function TestDll(str:string):string;stdcall; external ’Delphi.dll’;



procedure TForm1.Button1Click(Sender: TObject);

begin

Edit2.Text:=TestDll(Edit2.Text);

end;


1.概论   先来阐述一下DLL(Dynamic Linkable Library)的概念,你可以简单的把DLL看成一种仓,它提供给你一些可以直接拿来用的变量、函数或类。在仓的发展史上经历了“无-静态链接动态链接”的时代。   静态链接动态链接都是共享代码的方式,如果采用静态链接,则无论你愿不愿意,lib中的指令都被直接包含在最终生成的EXE文件中了。但是若使用DLL,该DLL不必被包含在最终EXE文件中,EXE文件执行时可以“动态”地引用和卸载这个与EXE独立的DLL文件。静态链接动态链接的另外一个区别在于静态链接中不能再包含其他的动态链接或者静态,而在动态链接中还可以再包含其他的动态或静态链接。   对动态链接,我们还需建立如下概念:   (1)DLL 的编制与具体的编程语言及编译器无关   只要遵循约定的DLL接口规范和调用方式,用各种语言编写DLL都可以相互调用。譬如Windows提供的系统DLL(其中包括了Windows的API),在任何开发环境中都能被调用,不在乎其是Visual Basic、Visual C++还是Delphi。   (2)动态链接随处可见   我们在Windows目录下的system32文件夹中会看到kernel32.dll、user32.dll和gdi32.dll,windows的大多数API都包含在这些DLL中。kernel32.dll中的函数主要处理内存管理和进程调度;user32.dll中的函数主要控制用户界面;gdi32.dll中的函数则负责图形方面的操作。   一般的程序员都用过类似MessageBox的函数,其实它就包含在user32.dll这个动态链接中。由此可见DLL对我们来说其实并不陌生。   (3)VC动态链接的分类   Visual C++支持三种DLL,它们分别是Non-MFC DLL(非MFC动态)、MFC Regular DLL(MFC规则DLL)、MFC Extension DLL(MFC扩展DLL)。   非MFC动态不采用MFC类结构,其导出函数为标准的C接口,能被非MFC或MFC编写的应用程序所调用;MFC规则DLL 包含一个继承自CWinApp的类,但其无消息循环;MFC扩展DLL采用MFC的动态链接版本创建,它只能被用MFC类编写的应用程序所调用

5,392

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧