zoukankan      html  css  js  c++  java
  • DLL与EXE之间的通讯调用 以及 回调函数的线程执行空间

      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

  • 相关阅读:
    45 个非常有用的 Oracle 查询语句
    [转载]java图片缩放处理
    [转载]java图片缩放处理
    十步完全理解SQL
    十步完全理解SQL
    day04_20170521_函数(二)
    to disable the entity lazy load, The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.
    wordpress mobile templates
    linq query, using int.parse to convert varchar to int while orderby
    appfabric 简单应用
  • 原文地址:https://www.cnblogs.com/findumars/p/5087499.html
Copyright © 2011-2022 走看看