码迷,mamicode.com
首页 > 编程语言 > 详细

DLL与EXE之间的通讯调用 以及 回调函数的线程执行空间

时间:2015-12-30 00:06:24      阅读:259      评论:0      收藏:0      [点我收藏+]

标签:

  dll 与 exe 之间的通讯方式有很多种, 本文采用回调函数的方法实现, 本文也将研究多线程,多模块的情况下,回调函数所在的线程, 啥也不说了,先附上代码:

 

下面的是dll模块的的, dll的工程文件:

 

[delphi] view plaincopy
 
  1. library DllAPP;  
  2.   
  3. uses  
  4.   windows,  
  5.   SysUtils,  
  6.   Classes,  
  7.   DllClass in ‘DllClass.pas‘;  
  8.   
  9. {$R *.res}  
  10.   
  11.   
  12.  var  
  13.   GDllServer: TDllServer;  
  14.   
  15.   function AddServer(ADispatchFunc: TDispatchFunc): HRESULT; stdcall;  
  16.   begin  
  17.     Result := ERROR_INVALID_FUNCTION;  
  18.     if not Assigned(GDllServer) then  
  19.       Exit;  
  20.     GDllServer.AddServer(ADispatchFunc);  
  21.     Result := ERROR_SUCCESS;  
  22.   end;  
  23.   
  24.   function DataDispatch(ACommand: Integer):HRESULT; stdcall;  
  25.   begin  
  26.     Result := ERROR_INVALID_FUNCTION;  
  27.     GDllServer.DataDispatch(ACommand);  
  28.     Result := 0;  
  29.   end;  
  30.   
  31.   function DLLInitialize: HRESULT;  
  32.   begin  
  33.     Result := 1;  
  34.     GDllServer := TDllServer.create;  
  35.     Result := ERROR_SUCCESS;  
  36.   end;  
  37.   
  38.   function  DllFinalize: HRESULT;  
  39.   begin  
  40.     Result := ERROR_INVALID_FUNCTION;  
  41.     GDllServer.Free;  
  42.     GDllServer := nil;  
  43.     Result := ERROR_SUCCESS;  
  44.   end;  
  45.   
  46. exports  
  47.   AddServer,  
  48.   DataDispatch,  
  49.   DLLInitialize,  
  50.   DllFinalize;  
  51.       
  52. begin  
  53. end.  

 

dll中的类型文件

 

[delphi] view plaincopy
 
  1. unit DllClass;  
  2.   
  3. interface  
  4.   
  5. uses  
  6.   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,  
  7.   Dialogs, StdCtrls;  
  8.   
  9.   
  10. type  
  11.   TDispatchFunc = function(ACommand: Integer): HRESULT;stdcall;  
  12.   
  13. type  
  14.   TDLLSERVER = CLAss;  
  15.   
  16.   TDLLThread = class(TThread)  
  17.   private  
  18.     FCount: Integer;  
  19.     FDllServer: TDllServer;  
  20.   public  
  21.     procedure Execute; override;  
  22.   public  
  23.     constructor create;  
  24.   end;  
  25.   
  26.   TDllServer = class  
  27.   private  
  28.     FDispatchFunc: TDispatchFunc;  
  29.     FDllThread: TDLLThread;  
  30.   public  
  31.     procedure AddServer(ADispatchFunc: TDispatchFunc);  
  32.     procedure DataDispatch(ACommand: Integer);  
  33.   public  
  34.     constructor Create;  
  35.     destructor Destroy;  
  36.   end;  
  37.   
  38. implementation  
  39.   
  40. { TDllServer }  
  41.   
  42. ///保存exe的回调函数指针  
  43. procedure TDllServer.AddServer(ADispatchFunc: TDispatchFunc);  
  44. begin  
  45.   FDispatchFunc := ADispatchFunc;  
  46. end;  
  47.   
  48. constructor TDllServer.create;  
  49. var  
  50.   LThreadID: Cardinal;  
  51. begin  
  52. ///  
  53.   LThreadID := GetCurrentThreadid;  
  54.   ShowMessage(‘DLL,create:‘+IntToStr(LThreadID));  
  55.   FDllThread := TDLLThread.create;  
  56.   FDllThread.FDllServer := Self;  
  57.   FDllThread.Resume;  
  58. end;  
  59.   
  60. ///DLL接受exe传过来的指令, dll留给exe的调用借口  
  61. procedure TDllServer.DataDispatch(ACommand: Integer);  
  62. var  
  63.   LThreadID: Cardinal;  
  64. begin  
  65.   if not Assigned(FDispatchFunc) then  
  66.     Exit;  
  67.   FDispatchFunc(ACommand);  
  68.   LThreadID := GetCurrentThreadid;  
  69.   ShowMessage(‘DLL,DateDispatch:‘+IntToStr(LThreadID));  
  70. end;  
  71.   
  72. destructor TDllServer.Destroy;  
  73. begin  
  74. ////  
  75. end;  
  76.   
  77. { TDLLThread }  
  78.   
  79. constructor TDLLThread.create;  
  80. var  
  81.   LThreadID: Cardinal;  
  82. begin  
  83.   FCount := 0;  
  84.   inherited create(True);  
  85. end;  
  86.   
  87. //这个函数的目的就是检验不同模块下的不同线程下,回调函数的执行线程  
  88. procedure TDLLThread.Execute;  
  89. var  
  90.   LThreadID: Cardinal;  
  91. begin  
  92.   inherited;  
  93.   while not Terminated do  
  94.   begin  
  95.     Inc(FCount);  
  96.     if FCount = 2  then  
  97.     begin  
  98.       LThreadID := GetCurrentThreadid;  
  99.       ShowMessage(‘DLL,Thread--‘+IntToStr(LThreadID));  
  100.     end;  
  101.     if FCount = then  
  102.     begin  
  103.       if assigned(FDllServer) then  
  104.       begin  
  105.         FDllServer.FDispatchFunc(2);  
  106.       end;  
  107.         
  108.     end;  
  109.     Sleep(1000);  
  110.   end;  
  111. end;  
  112.   
  113. end.  

 

 

exe的文件

 

[c-sharp] view plaincopy
 
  1. unit ExeClass;  
  2.   
  3. interface  
  4.   
  5. uses  
  6.   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,  
  7.   Dialogs, StdCtrls;  
  8.   
  9. type  
  10.   TDispatchFunc = function (ACommand: Integer): HRESULT;stdcall;  
  11.   TServerFunc = function (ADispatchFunc: TDispatchFunc): HRESULT;stdcall;  
  12.   TProc = function: HRESULT;  
  13.   
  14. type  
  15.   TForm2 = class(TForm)  
  16.     Button1: TButton;  
  17.     Memo1: TMemo;  
  18.     procedure FormDestroy(Sender: TObject);  
  19.     procedure Button1Click(Sender: TObject);  
  20.     procedure FormCreate(Sender: TObject);  
  21.   private  
  22.     { Private declarations }  
  23.     FServerDispatch: TServerFunc;    ///exe--->dll  
  24.     FDataDispatch: TDispatchFunc;    ///EXE--->DLL  
  25.     FDllInitialize: TProc;  
  26.     FDllFinalize: TProc;  
  27.   public  
  28.     { Public declarations }  
  29.   end;  
  30.   
  31. var  
  32.   Form2: TForm2;  
  33.   GHandleLibrary: THandle;  
  34.   GCount: Integer;  
  35.   
  36. implementation  
  37.   
  38. {$R *.dfm}  
  39.   
  40. ///DLL--->EXE,留给dll调用的回调函数  
  41. function DataDispatch(ACommand: Integer): HRESULT; stdcall;  
  42. var  
  43.   LThreadID: Cardinal;  
  44. begin  
  45.   LThreadID := GetCurrentThreadid;  
  46.   ShowMessage(‘EXE:‘+IntToStr(LThreadID));  
  47. end;  
  48.   
  49. procedure TForm2.Button1Click(Sender: TObject);  
  50. begin  
  51.   Inc(GCount);  
  52.   FDataDispatch(GCount);  
  53. end;  
  54.   
  55. procedure TForm2.FormDestroy(Sender: TObject);  
  56. begin  
  57.   FDllFinalize;  
  58.   FServerDispatch := nil;  
  59.   FDataDispatch := nil;  
  60.   FDllInitialize := nil;  
  61.   FDllFinalize := nil;  
  62.   FreeLibrary(GHandleLibrary);  
  63. end;  
  64.   
  65. procedure TForm2.FormCreate(Sender: TObject);  
  66. var  
  67.   LThreadID: Cardinal;  
  68. begin  
  69.   GHandleLibrary := LoadLibrary(PChar(‘DLLAPP.dll‘));  
  70.   @FDllInitialize := GetProcAddress(GHandleLibrary, ‘DLLInitialize‘);  
  71.   @FDllFinalize := GetProcAddress(GHandleLibrary, ‘DllFinalize‘);  
  72.   @FServerDispatch := GetProcAddress(GHandleLibrary, ‘AddServer‘);  
  73.   @FDataDispatch := GetProcAddress(GHandleLibrary,‘DataDispatch‘);  
  74.   FDllInitialize;  
  75.   FServerDispatch(DataDispatch);  
  76.   LThreadID := GetCurrentThreadid;  
  77.   Memo1.Lines.Add(IntToStr(LThreadID));  
  78. end;  
  79.   
  80. end.  

1,简单实现的dll与exe之间的通讯, 其实就是利用了dll的导出函数, 先想dll传递一个回调函数的地址,供dll面向exe的通讯。 exe面向dll 的通讯直接执行dll导出函数即可

2, 本文是最基本的实现,当然其中的回调函数,以及dll的处理函数,可以在数据包的级别上实现, 即: 定义不同数据包,根据命令执行不同的函数, 这样只要导出一个函数,保留一个回调函数 就可以实现大量的功能

3, 关于回调函数的线程执行空间,取决于调用者所在的线程, 比如dll线程中回调exe的函数, 则回调函数是执行在该dll线程。 如果是主线程执行回调,则在主线程。 上述代码GDLLclass的创建过程是导出函数,所以GDLLclass的主线程就是exe的主线程,他们在一个线程空间

 

http://blog.csdn.net/procedure1984/article/details/3985127

DLL与EXE之间的通讯调用 以及 回调函数的线程执行空间

标签:

原文地址:http://www.cnblogs.com/findumars/p/5087499.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!