| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2753 人关注过本帖
标题:请教DLL定时器的问题
只看楼主 加入收藏
yalewang
Rank: 2
等 级:论坛游民
帖 子:125
专家分:35
注 册:2010-4-15
收藏
得分:0 
library dlltest1;
uses
  SysUtils,
  Classes;
var
x,y,z:integer;
{$R *.res}
procedure read(str:string);/////////////
begin
   x:=random(100)    ;
   y:=random(30);      ;
end;

procedure TimerProc(hWn:HWND,nMsg:integer,nTimerid: DWORD,dwTime:DWORD);stdcall;
我在这里设置回调函数,也就是事件处理过程?
begin
     read("dddd");//调用读过程

     function Add():integer;stdcall;//定义DLL的输出函数(无参)
        begin
        z:=x+y;
        result:= z;
        end;
     timerdelete;//删除定时器
end;

exports
Add;

begin///////在dll的初始化模块中设置定时器的创立及删除
   procedure timercreate(Sender: TObject);
       var
       identer:integer;
       begin
       identer:=settimer(0,1,2000,@TimerProc);//handle为null或0
       end;
    procedure timerdelete(Sender: TObject);
       begin
         KillTimer(0, 1);
       end;

end.

上面是根据我的理解所写,请指教



[ 本帖最后由 yalewang 于 2010-7-23 15:01 编辑 ]
2010-07-23 11:47
东海一鱼
Rank: 13Rank: 13Rank: 13Rank: 13
等 级:贵宾
威 望:48
帖 子:757
专家分:4760
注 册:2009-8-10
收藏
得分:0 
不好意思,我刚看到。昨晚以为一直没有更新。
library dlltest1;
uses
  SysUtils,
  windows,                 //引用windows单元,需要调用系统API的话,都要引用这个单元  
  Classes;
var
x,y,z,TimeID:integer;     //这里加个TimeID变量,因为没有窗口的话,TimeID是由系统指定的。        
{$R *.res}
procedure read(str:string);/////////////
begin
   x:=random(100)    ;
   y:=random(30);      ;
end;

procedure TimerProc(hWn:HWND,nMsg:integer,nTimerid: DWORD,dwTime:DWORD);stdcall;
我在这里设置回调函数,也就是事件处理过程?
begin
     read("dddd");//调用读过程

     function Add():integer;stdcall;//定义DLL的输出函数(无参)
        begin
        z:=x+y;
        result:= z;
        end;
     timerdelete;//删除定时器
end;

exports
Add;

begin///////在dll的初始化模块中设置定时器的创立及删除
   procedure timercreate(Sender: TObject);
       var
       //identer:integer;            //这个就不用了,因为要跨函数使用,所以要用全局变量
       begin
       TimeID:=settimer(0,1,2000,@TimerProc);//handle为null或0  //1是你给定时器的编号,有窗口的话他就是TimeID,无窗口则系统返回真正的TimeID.
       end;
    procedure timerdelete(Sender: TObject);
       begin
         KillTimer(0, TimeID);                 //这个就不用解释了吧。           
       end;

end.

举世而誉之而不加劝,举世而非之而不加沮,定乎内外之分,辩乎荣辱之境,斯已矣。彼其于世未数数然也。
2010-07-24 10:18
yalewang
Rank: 2
等 级:论坛游民
帖 子:125
专家分:35
注 册:2010-4-15
收藏
得分:0 
编译器提示有以下错误
1、procedure TimerProc(hWn:HWND,nMsg:integer,nTimerid: DWORD,dwTime:DWORD);stdcall
 形参之间用  分号
2、 procedure timercreate(Sender: TObject);   此处不能有声明
3、function Add():integer;stdcall               此处不能有声明
   (好像不能嵌套定义,)
根据提示进行修改,勉强通过编译,放入调用程序,函数输出始终为0;
random没发挥作用,定时没触发。
我改过的代码如下:

uses
  SysUtils,
  windows,
  Classes;
var
x,y,z,TimeID:integer;
{$R *.res}
procedure read(str:string);/////////////
begin
   x:=random(100);
   y:=random(30);
end;

procedure TimerProc(hWn:HWND;nMsg:integer;nTimerid:DWORD;dwTime:DWORD);stdcall;
begin
     read('dddd');
     //timerdelete;
end;
 function Add():integer;stdcall;
        begin
        z:=x+y;
        result:= z;
        end;
exports
Add;
begin
   //procedure timercreate(Sender: TObject);

    //   begin
       TimeID:=settimer(0,1,2,@TimerProc);
     //  end;
    //procedure timerdelete(Sender: TObject);
    //   begin
         KillTimer(0, TimeID);
    //   end;

end.
2010-07-24 11:21
东海一鱼
Rank: 13Rank: 13Rank: 13Rank: 13
等 级:贵宾
威 望:48
帖 子:757
专家分:4760
注 册:2009-8-10
收藏
得分:0 
老兄需要多看看delphi的基础书啊。
我写了一个测试,希望能对你有帮助:
dll代码:
程序代码:
library Project1;
uses
  SysUtils,
  windows,
  Classes;

  type
    OutFn = procedure(OutVal: Integer);stdcall;

{$R *.res}
var
  CallFun: OutFn;
  TimeID: Integer;

function Add(hwn:HWND;msg:Integer;TimeFlg: Integer;
  TimeElp:DWORD):Integer;stdcall;
var
  x,y,z: Integer;
begin
  Result:= 0;

  if pInteger(@CallFun)^ <> 0 then
  begin
    y:= random(300);
    z:= random(750);
    x:= y * z;
    CallFun(x);
    Result:= 1;
  end;
end;

function Start(TimeFlg: Integer;TimeElp: DWORD):BOOL;stdcall;
begin
  Result:= False;

  TimeID:= SetTimer(0,TimeFlg,TimeElp,@Add);
  if TimeID <> 0 then
    Result:= True;
end;

function Stop:BOOL;stdcall;
begin
  Result:= KillTimer(0,TimeID);
end;

function Init(Fn: OutFn):BOOL;stdcall;
begin
  Result:= False;

  if pInteger(@Fn)^ <> 0 then
  begin
    CallFun:= Fn;
    Result:= True;
  end;
end;

exports
Stop,
Start,
Init;

begin
  CallFun:= OutFn(Nil);
  TimeID:= 0;
end.

测试代码:
程序代码:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  OutFn = procedure(OutVal: Integer);stdcall;

  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}
function Start(TimeFlg: Integer;
  TimeElp: DWORD):BOOL;stdcall;external 'Project1.dll';
function Stop:BOOL;stdcall;external 'Project1.dll';
function Init(Fn: OutFn):BOOL;stdcall;external 'Project1.dll';

procedure Playout(OutValue: Integer);stdcall;
begin
  Form1.Memo1.Lines.Add(IntToStr(OutValue));
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Init(@Playout);
  Start(1,500);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  Stop;
end;

end.
编译附件:
TestTimerDll.rar (197.67 KB)


举世而誉之而不加劝,举世而非之而不加沮,定乎内外之分,辩乎荣辱之境,斯已矣。彼其于世未数数然也。
2010-07-24 17:24
yalewang
Rank: 2
等 级:论坛游民
帖 子:125
专家分:35
注 册:2010-4-15
收藏
得分:0 
鱼兄,你可给我出了一个大题目,定义了过程变量,从没接触过。
经常受木马所侵,想学一下制作和防御也这这么难,有点灰心,
刚又杀了一个木马project1.exe     不服气



有没有简单的办法制作我讲的定时器?我所讲的定时器是在DLL内部触发事件,
来读取数据,经计算后由输出函数传给调用DLL的程序

[ 本帖最后由 yalewang 于 2010-7-24 22:14 编辑 ]
2010-07-24 22:11
东海一鱼
Rank: 13Rank: 13Rank: 13Rank: 13
等 级:贵宾
威 望:48
帖 子:757
专家分:4760
注 册:2009-8-10
收藏
得分:0 
windows的定时器就两种工作方式:
窗口的消息方式和函数回调方式。

确切的说,只有一种工作方式。就是回调函数方式,窗口的消息方式,
实际上是操作系统帮你把回调函数安排在了窗口的处理函数上。

定意过程函数的目的,就是为了使用回调函数。这是你必须掌握的。而且
它一点也不难啊,你就把他当成普通指针变量看待就行了。



举世而誉之而不加劝,举世而非之而不加沮,定乎内外之分,辩乎荣辱之境,斯已矣。彼其于世未数数然也。
2010-07-25 09:58
yalewang
Rank: 2
等 级:论坛游民
帖 子:125
专家分:35
注 册:2010-4-15
收藏
得分:0 
以下是引用东海一鱼在2010-7-24 17:24:55的发言:

老兄需要多看看delphi的基础书啊。
我写了一个测试,希望能对你有帮助:
dll代码:
library Project1;
uses
  SysUtils,
  windows,
  Classes;
 
  type
    OutFn = procedure(OutVal: Integer);stdcall;
 
{$R *.res}
var
  CallFun: OutFn;
  TimeID: Integer;
 
function Add(hwn:HWND;msg:Integer;TimeFlg: Integer;
  TimeElp:DWORD):Integer;stdcall;
var
  x,y,z: Integer;
begin
  Result:= 0;
 
  if pInteger(@CallFun)^ <> 0 then
  begin
    y:= random(300);
    z:= random(750);
    x:= y * z;
    CallFun(x);
    Result:= 1;
  end;
end;
 
function Start(TimeFlg: Integer;TimeElp: DWORD):BOOL;stdcall;
begin
  Result:= False;
 
  TimeID:= SetTimer(0,TimeFlg,TimeElp,@Add);
  if TimeID <> 0 then
    Result:= True;
end;
 
function Stop:BOOL;stdcall;
begin
  Result:= KillTimer(0,TimeID);
end;
 
function Init(Fn: OutFn):BOOL;stdcall;
begin
  Result:= False;
 
  if pInteger(@Fn)^ <> 0 then
  begin
    CallFun:= Fn;
    Result:= True;
  end;
end;
 
exports
Stop,
Start,
Init;
 
begin
  CallFun:= OutFn(Nil);
  TimeID:= 0;
end.
测试代码:
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;
 
type
  OutFn = procedure(OutVal: Integer);stdcall;
 
  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
function Start(TimeFlg: Integer;
  TimeElp: DWORD):BOOL;stdcall;external 'Project1.dll';
function Stop:BOOL;stdcall;external 'Project1.dll';
function Init(Fn: OutFn):BOOL;stdcall;external 'Project1.dll';
 
procedure Playout(OutValue: Integer);stdcall;
begin
  Form1.Memo1.Lines.Add(IntToStr(OutValue));
end;
 
procedure TForm1.Button1Click(Sender: TObject);
begin
  Init(@Playout);
  Start(1,500);
end;
 
procedure TForm1.Button2Click(Sender: TObject);
begin
  Stop;
end;
 
end.编译附件:
恭喜鱼兄荣升版主。
上面的代码看了好长时间,还难理解,能否做个注释。
尤其是
if pInteger(@Fn)^ <> 0
.....
 CallFun(x);

这两句。
谢谢
2010-07-29 09:19
东海一鱼
Rank: 13Rank: 13Rank: 13Rank: 13
等 级:贵宾
威 望:48
帖 子:757
专家分:4760
注 册:2009-8-10
收藏
得分:0 
library Project1;
uses
  SysUtils,
  windows,
  Classes;

  type
    OutFn = procedure(OutVal: Integer);stdcall;          //定义一个变量类型,类型为函数指针

{$R *.res}
var
  CallFun: OutFn;                     //声明一个函数指针的变量
  TimeID: Integer;

function Add(hwn:HWND;msg:Integer;TimeFlg: Integer;
  TimeElp:DWORD):Integer;stdcall;
var
  x,y,z: Integer;
begin
  Result:= 0;

  if pInteger(@CallFun)^ <> 0 then     //判断这个函数指针是否是空指针
  begin
    y:= random(300);
    z:= random(750);
    x:= y * z;
    CallFun(x);                 //不为空,就调用它。   
    Result:= 1;
  end;
end;

function Start(TimeFlg: Integer;TimeElp: DWORD):BOOL;stdcall;
begin
  Result:= False;

  TimeID:= SetTimer(0,TimeFlg,TimeElp,@Add);
  if TimeID <> 0 then
    Result:= True;
end;

function Stop:BOOL;stdcall;
begin
  Result:= KillTimer(0,TimeID);
end;
//初始化函数
function Init(Fn: OutFn):BOOL;stdcall;    //注意传进来的参数类型为OutFn,再看看上面OutFn的定义
begin
  Result:= False;

  if pInteger(@Fn)^ <> 0 then      //判断这个函数指针是否是空指针
  begin
    CallFun:= Fn;                 //不为空,则赋给我的函数指针变量保存起来。
    Result:= True;
  end;
end;

exports
Stop,
Start,
Init;

begin
  CallFun:= OutFn(Nil);    //DLL加载代码,先给我的函数指针变量赋空值
  TimeID:= 0;
end.



举世而誉之而不加劝,举世而非之而不加沮,定乎内外之分,辩乎荣辱之境,斯已矣。彼其于世未数数然也。
2010-07-29 10:20
yalewang
Rank: 2
等 级:论坛游民
帖 子:125
专家分:35
注 册:2010-4-15
收藏
得分:0 
鱼兄上面的DLL输出函数Init能否改成无参数的
另外自己在写DLL时遇到DWord、THandle的数据类型没有声明,怎解决?需添加什么单元,谢谢
2010-07-31 03:18
东海一鱼
Rank: 13Rank: 13Rank: 13Rank: 13
等 级:贵宾
威 望:48
帖 子:757
专家分:4760
注 册:2009-8-10
收藏
得分:0 
Init的目的就是要传入回调函数的地址。如果没有,就只好用消息机制了(传递窗口句柄)。
procedure Playout(OutValue: Integer);stdcall;  //这是我的回调函数
begin
  Form1.Memo1.Lines.Add(IntToStr(OutValue));   //什么也不做,只把每次传入的值输出到显示
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Init(@Playout);                            //OK,传入上面函数的地址
  Start(1,500);                              //启动定时器
end;
其实上面的很简单,你照这比划两次就明白了。

另外自己在写DLL时遇到DWord、THandle的数据类型没有声明,怎解决?
加入windows就好。



举世而誉之而不加劝,举世而非之而不加沮,定乎内外之分,辩乎荣辱之境,斯已矣。彼其于世未数数然也。
2010-07-31 10:32
快速回复:请教DLL定时器的问题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.040694 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved