我在使用Indy的TIdUDPServer,在EXE中完全正常,但是换到DLL中就关闭不了。具体如下:library dllclient;{ 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,
  Windows,
  Unit2 in 'Unit2.pas' {DataModule2: TDataModule};{$R *.res}//初始化模块
procedure InitDLL;
begin
  if not Assigned(DataModule2) then
    DataModule2:=TDataModule2.Create(nil);
end;//释放模块
procedure CloseDLL;
begin
  if assigned(DataModule2) then
  begin
     DataModule2.Free ;
     DataModule2 := nil;
  end;
end;//--------------------下面是主要功能函数------------------//
function SendUDP():integer;stdcall;
var
  ss:string;
begin
   ss := formatdatetime('DLL Send yyyy-mm-dd hh:nn:ss',now());
   DataModule2.IdUDPServer1.Send('192.168.1.99',55354,ss);
   result := 1;
end;
//-------------------功能函数结束---------------------------//
//该DLL的入口
Procedure TheProc(Flag:DWORD);
begin
 case Flag of
  DLL_PROCESS_ATTACH:InitDLL;
  DLL_PROCESS_DETACH:CloseDLL;
 end;
end;exports
 SendUDP;
begin
 DLLPROC:=@TheProc;
 TheProc(DLL_PROCESS_ATTACH);
end.//--------------------------------------------unit Unit2;interfaceuses
  SysUtils, Classes, IdBaseComponent, IdComponent, IdUDPBase, IdUDPServer,
  IdSocketHandle;type
  TDataModule2 = class(TDataModule)
    IdUDPServer1: TIdUDPServer;
    procedure DataModuleCreate(Sender: TObject);
    procedure DataModuleDestroy(Sender: TObject);
    procedure IdUDPServer1UDPRead(Sender: TObject; AData: TStream;
      ABinding: TIdSocketHandle);
  private
    { Private declarations }
  public
    { Public declarations }
  end;var
  DataModule2: TDataModule2;
  strMsgList:TStringList;implementation{$R *.dfm}procedure TDataModule2.DataModuleCreate(Sender: TObject);
begin
   if not IdUDPServer1.Active then IdUDPServer1.Active := true;
   if not assigned(strMsgList) then strMsgList := TStringList.Create ;
end;procedure TDataModule2.DataModuleDestroy(Sender: TObject);
begin
   if IdUDPServer1.Active then
    IdUDPServer1.Active := false;
   if assigned(strMsgList) then
   begin
      strMsgList.Free ;
      strMsgList := nil;
   end;
end;procedure TDataModule2.IdUDPServer1UDPRead(Sender: TObject; AData: TStream;
  ABinding: TIdSocketHandle);
var
  ss:string;
  sstemp:string[100];
begin
   //UDP数据读入
   ss := abinding.PeerIP ;
   adata.ReadBuffer(sstemp,AData.Size);
   if assigned(strMsgList) then
     strMsgList.Append(ss+' '+sstemp);
end;end.
程序该DM在EXE中运行一切正常,在DLL中接发数据也正常,就是DLL关闭的时候
    IdUDPServer1.Active := false; 该语句无法通过,运行到这里停止。
郁闷。

解决方案 »

  1.   

    经过研究把释放部分修改成下面,代码可以运行下去。不过,DLL释放的时候程序出错,应该是还有线程没有释放。修改后的代码如下:   if IdUDPServer1.Active then
       begin
          IdUDPServer1.Bindings.Clear ;
          IdUDPServer1.Active := false;
       end;看来是跟线程释放方面有关的。
    ......继续研究。。
      

  2.   

    { 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
    ShareMem;
    最好使用pchar 不使用string
      

  3.   

    也不是这个问题,如果我的exe是用delphi写的,可以不用理会这个问题。再说DLL调用函数中没有涉及string的问题。就算我不发数据就把active这样true、false一下,DLL关闭也是出错的。
      

  4.   

    无法解决我最后是用了TCPServer来代替UDPServer如果我在DLL中使用了UDPServer就会无法active为false,可能是indy的bug.........