unit useDll;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtDlgs;type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    Button2: TButton;
    OpenDialog1: TOpenDialog;
    Label1: TLabel;
    Button3: TButton;
    Button4: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormDestroy(Sender: TObject);
    procedure Button4Click(Sender: TObject);  private
  Th:Thandle;
    { Private declarations }
  public
    { Public declarations }
  end;var
  Form1: TForm1;  procedure OpenWinsocket(
  ServerIP:string;port:integer;sfileName:string);stdcall; external
  'SentFile.dll' ;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
begin
try
if OpenDialog1.Execute then
edit1.Text:=OpenDialog1.FileName;
except
end;
end;procedure TForm1.Button2Click(Sender: TObject);
begin
{
if edit1.Text='' then
edit1.Text:= 'D:\ks.doc';
}
try
 OpenWinsocket('192.168.1.1',1225,trim(edit1.Text));
 except
 end;end;
procedure TForm1.Button3Click(Sender: TObject);
type
TIntFunc=procedure(ServerIP:string;port:integer;sfileName:string);stdcall;
var
//Th:Thandle;
Tf:TIntFunc;
Tp:TFarProc;
s:bool;
begin
Th:=LoadLibrary('SentFile.dll'); //装载DLL
if Th>0 then
try
Tp:=GetProcAddress(Th,PChar('OpenWinsocket'));
if Tp<>nil then begin
Tf:=TIntFunc(Tp); 
Tf('192.168.1.1',1225,trim(edit1.Text)); 
end
else
ShowMessage('函数没有找到');
finally
//FreeLibrary(Th); {释放DLL
end
else
ShowMessage('SentFile.dll没有找到');
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
FreeLibrary(Th);
//Form1.Free;
//Form1:=nil;
action:=cafree;
end;procedure TForm1.FormDestroy(Sender: TObject);
begin
//Form1:=nil;
end;procedure TForm1.Button4Click(Sender: TObject);
begin
application.Terminate
end;end.

解决方案 »

  1.   

    静态声明的动态库调用不要手动Free.
      

  2.   

      procedure OpenWinsocket(
      ServerIP:string;port:integer;sfileName:string);stdcall; external
      'SentFile.dll' ;
    ===============
    如果要自己手工LoadLibrary,则把后面的external...去掉,手工管理。
      

  3.   

    可以说是delphi问题(如果delphi做的再好一点可能不会这样)
    问题在动态库内部,可能需要borlandmm.dll(类似,具体名称不记得),如果换不行就尽可能避免该错误
    我一般在动态库中,不使用string等特有数据类型,避免该类问题,不再深究
    procedure OpenWinsocket(
      ServerIP:string;port:integer;sfileName:string);stdcall; external
      'SentFile.dll' ;
      

  4.   

    procedure OpenWinsocket( 
    所在的单元文件  OpenWinsocket( 
    有问题
      

  5.   

    procedure OpenWinsocket(
      ServerIP:string;port:integer;sfileName:string);stdcall; external
      'SentFile.dll' ;
    中  external 'SentFile.dll' ;有点多余了吧 
      

  6.   

    procedure OpenWinsocket(
      ServerIP:string;port:integer;sfileName:string);stdcall; external
      'SentFile.dll' ;这个dll是使用delphi编写的吗?如果是你修改一下你的dll将string类型修改成pchar类型,虽然uses ShareMem可能会解决这样的问题,但是还是不建议在dll中使用string类型
      

  7.   

    { 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. }每个 dll project 都会有这个提示。
      

  8.   

    楼上都对。在Delphi中使用DLL要注意两点:
    1、如果用 LoadLibrary就不要以external方式声明函数;
    2、尽量不使用delphi独有的类型
      

  9.   

    dll与宿主程序的application不同,所以应该先把宿主的application传给dll,否则程序退出时出错
      

  10.   

    如果想要用String类型,文件头第一个加上 uses Sharemem,否则要用PChar类型传递字符串参数。