读书 - Delphi下深入Windows核心编程 第一天

技术交流,DH讲解.

晚上突然有这个想法,该踏踏实实把所有的书读一遍,好吧.踏实一些.
这本书,我也只有电子版,要下的人可以去盒子,园地还有我的网盘都有.

第一章 DLL和数据共享
首先建立一个DLL工程:
image
image
导出函数的2种方式:

function Export1():Integer ; export;
begin
  //add code here
end;

就是在函数后面写个export.

function Export1():Integer ;
begin
  //add code here
end;

function Export2():Cardinal ;stdcall;
begin
  //add code here
end;

exports
  Export1,Export2;

exports后面把所有要导出的函数名字写上.
exe调用Dll也有2种方式:
显式调用:

function Export1():Integer;external 'Project2.dll';

implementation

定义一个函数,然后external 说明这个函数来之哪个dll.这样就不用实现了.
隐式调用:

type
  TExport2 = function : Cardinal;stdcall;
procedure TForm1.FormCreate(Sender: TObject);
var
  hLib:Cardinal;
  Export2:TExport2;
begin
  hLib:=LoadLibrary('Project2.dll');
  Export2:=TExport2(GetProcAddress(hLib,'Export2'));
  //执行函数
  Export2;
  FreeLibrary(hLib);
end;

先用LoadLibary加载Dll然后GetProcAddress来取得函数指针,然后执行,最后释放dll句柄,记得.
既然说到了调用,这里就要说调用约定了:
            register       函数体      从左到右,优先使用寄存器(EAX,EDX,ECX),然后使用堆栈
            pascal         函数体      从左到右,通过堆栈传递
            cdecl           调用者      从右到左,通过堆栈传递(与C\C++默认调用约定兼容)
            stdcall         函数体      从右到左,通过堆栈传递(与VC中的__stdcall兼容)
            safecall       函数体      从右到左,通过堆栈传递(同stdcall)

我们看见传参不一样我调用的方式要是不一样,那么参数就可能不对了,函数最后的结果肯定不一样了.
如果我们想在Dll初始化干点儿事,结束时干点儿事,怎么办?

//Dll工程文件的末尾的Begin End中间
begin
  //这里写代码就是初始化了,但是这样只能初始化干事情
end.

只能初始化...那怎么办?
解决方法又有2个,哈哈:
第一个,我们添加一个引用单元,然后这个单元initialization和finalization进行初始化和收尾工作塞.

uses
  Unit2 in 'Unit2.pas';//Dll添加引用单元
unit Unit2;

interface
uses
  SysUtils;

implementation
var
  L:TObject;

initialization
  L:=TObject.Create;//初始化工作

finalization
  L.Free; //收尾工作

end.

第二个,调用main函数,是的,dllmain(),不过Delphi里面不是叫这个,叫dllproc().

procedure MyDllMain(n:Integer);
begin
  case n of
    DLL_PROCESS_ATTACH:
      begin
        //进程加载Dll的时候
      end;
    DLL_PROCESS_DETACH:
      begin
        //进程卸载Dll的时候
      end;
    DLL_THREAD_ATTACH:
      begin
        //线程加载Dll的时候
      end;
    DLL_THREAD_DETACH:
      begin
        //线程卸载Dll的时候
      end;
  end;
end;

begin
  DllProc:=MyDllMain;
  MyDllMain(DLL_PROCESS_ATTACH);
end.

当Dll被一个进程加载之后,DLL的变量的空间就是这个进程里面了.也就是如果2个进程加载一个DLL,那么DLL的全局变量就有2个备份了,互不相干,是吧.
要多个DLL共享一个全局变量怎么办?接下来要说的就是用内存映射文件.

type
  TData = record
    A:Integer;
    //其他数据
  end;
  PData = ^TData;

var
  hMap:Cardinal;
  data:PData;

procedure MyDllMain(n:Integer);
begin
  case n of
    DLL_PROCESS_ATTACH:
      begin
        hMap:=OpenFileMapping(FILE_MAP_ALL_ACCESS,False,'名字');
        if hMap = 0 then//没有就创建
        begin
          //内存映射的话,第一个参数必须是$FFFFFFFF,文件映射的话就是文件句柄
          //第二个参数:安全,一般为nil
          //第三个参数:映射文件的属性,我们要可读可写
          //第四个参数:要映射数据大小的高4个字节
          //第五个参数:要映射数据大小的低4个字节
          //第六个参数:唯一的名字
          hMap:=CreateFileMapping($FFFFFFFF,nil,PAGE_READWRITE,0,SizeOf(TData),'名字');
          if hMap=0 then//创建失败
            Exit;
        end;
        //映射数据
        data:=MapViewOfFile(hMap,FILE_MAP_ALL_ACCESS,0,0,0);//全部映射出来
        if data = nil then//映射失败
          Exit;
      end;
    DLL_PROCESS_DETACH:
      begin
        if Boolean(data) then
        begin
          UnmapViewOfFile(data);
          CloseHandle(hMap);
        end;
      end;
  end;
end;

现在就映射好了,只要对data进行操作就会写到共享内存区了.因为可能多个DLL回去写,所以这里我们需要弄个互斥对象来同步.我就不演示了.这书上的代码里面会有的.
还有一个地方,映射的时候都只有一个变量一个结构体,结构体里面不要有指针,也就是像String这样的,因为指针指向的地址又是在进程空间中了.如果有多个结构体要共享,就需要先把多个结构体定义成一个结构体.

其他共享数据的方式:
1 SendMessage 或者 PostMessage,然后靠LPARAM和WPARAM来传递,但是LPARAM和WPARAM只是2个Integer,也就是传递的数据也就只有2个数,地址,指针没戏,因为你指针还是进程空间里面的,没有映射出来.
2 WM_COPYDATA消息可以传一个指针出来.

function SendCopyData(h:HWND;s:AnsiString):Integer ;
var
  p:PAnsiChar;
  bufsize:Integer;
  data:TCopyDataStruct;
begin
  bufsize:=Length(s) + 1;
  p:=AllocMem(bufsize);
  StrCopy(p,PAnsiChar(s));
  with data do
  begin
    cbData:=bufsize;
    dwData:=12315;//自己定义
    lpData:=p;
  end;
  Result:=SendMessage(h,WM_COPYDATA,0,Integer(@data))
end;

好的第一章就这样,准备睡觉.明天不能迟到了...

展开阅读全文

谁来和我一起读windows核心编程?[读书摘记]

11-16

一起来读windows核心编程rn -----windows核心编程读书摘记rnrnrnrn---------------------rn混csdn前期回顾:rn精选微软等数据结构+算法面试100题,整的一大半了,虽还只公布到第60题,rn但整天 看代码,也实在 趣味不多。详情见此帖:rn[url=http://topic.csdn.net/u/20101023/20/5652ccd7-d510-4c10-9671-307a56006e6d.html][/url]rnrn整理资源,下载地址:rn[最新答案V0.3版]微软等数据结构+算法面试100题[第21-40题答案]rn[url=http://download.csdn.net/source/2832862][/url]rnrn[第1题-60题汇总]微软等数据结构+算法面试100题rn[url=http://download.csdn.net/source/2826690][/url]rnrn[答案V0.2版]精选微软数据结构+算法面试100题[前20题]--修正rn[url=http://download.csdn.net/source/2813890][/url]rn//此份答案是针对最初的V0.1版本,进行的校正与修正。rnrn[答案V0.1版]精选微软数据结构+算法面试100题[前25题]rn[url=http://download.csdn.net/source/2796735][/url]rnrn[第二部分]精选微软等公司结构+算法面试100题[前41-60题]:rn[url=http://download.csdn.net/source/2811703][/url]rnrn[第一部分]精选微软等公司数据结构+算法经典面试100题[1-40题] rn[url=http://download.csdn.net/source/2778852][/url]rnrn更多资源,下载地址:rn[url=http://v_july_v.download.csdn.net/ ][/url]rn //目前,第61题-100题尚在整理中。rnrnrn近期闲着无事,正好静下心来,读点书。rn一翻windows核心编程,挺不错的,喜爱有加。rn又曾于前几天,看到论坛上,有人提问,寻求看windows核心编程的方法。rn一本好书,不用问怎么看,看就对了。尤其是一本世界级经典著作。rnrn楼主声明:rn1.本读书摘记以:[b]windows via c/c++(windows核心编程第五版 中文版),[/b]为准。rn2.欢迎各位,与我一起就此书交流,无论触及内容是深是浅,来者,一律不拒。rn 尤其是欢迎大方之家,对此书摘记 提出自己的 独到见解,或经验,于众网友共享。rn 特别精彩的回复,我愿慷慨解囊,送20分一人。rn 每发现此读书摘记中,一处内容错误,奖5分/人。rn3.希望,在微软面试题热浪之后,又能在论坛上刮起一阵热度 windows核心编程的热潮。:)...rn4.作者本人July对以下全部所有任何内容享有版权,转载请注明出处。rn先向你的厚道致敬。rn以下所有文字,都是一字一字敲出来的,请尊重他人劳动成果。rn谢谢。:)。rnrnrn不要问我,这样做,是为了什么。我告诉你,纯粹是为了练习打字。:)。rn如果,你内心浮躁,我想,你一定静不下心来,看我打的这一个一个子。rn这样,你就可以无视此帖,悄然飘过~。rnrnrnwindows核心编程完整中文版,下载地址:rn[极品收藏]Windows 核心编程完整中文pdf版(上)rn[url=http://download.csdn.net/source/2782631][/url]rnrn[极品收藏]Windows 核心编程完整中文pdf版(中)rn[url=http://download.csdn.net/source/2782639][/url]rnrn[极品收藏]Windows 核心编程完整中文pdf版(下)rn[url=http://download.csdn.net/source/2782654][/url]rnrn更多资源,下载地址:rn[url=http://v_july_v.download.csdn.net/ ][/url]rn //日后,我会上传windows核心编程英文版+最新的第5版中文版。 论坛

没有更多推荐了,返回首页