动态库代码如下:
library MyForms;
{ 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,Forms,
  DLLForm in 'DLLForm.pas' {FormDLL};function ShowForm:Integer;stdcall;
  var
    FormDll:TFormDLL; 
  begin
    FormDll:=TFormDll.Create(Application);
    Result:=FormDll.showmodal;
    FormDll.Free;
  end;
  exports
      ShowForm;
{$R *.res}begin
end.
动态库中的窗体上主要有ADOConnection1,ADOQuery1,DataSource1,DBGrid1,BitBtn1,BitBtn2等控件;窗体代码如下:
unit DLLForm;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls, Buttons, DB, ADODB, Grids, DBGrids, ActiveX,
  DBClient, MConnect, SConnect, DBTables;type
  TFormDLL = class(TForm)
    Panel1: TPanel;
    BitBtn1: TBitBtn;
    DataSource1: TDataSource;
    DBGrid1: TDBGrid;
    BitBtn2: TBitBtn;
    ADOConnection1: TADOConnection;
    ADOQuery1: TADOQuery;
    procedure BitBtn1Click(Sender: TObject);
    procedure BitBtn2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;var
  FormDLL: TFormDLL;
implementation
{$R *.dfm}
procedure TFormDLL.BitBtn1Click(Sender: TObject);
begin
  Close;
end;procedure TFormDLL.BitBtn2Click(Sender: TObject);
begin
  FormDLL.ADOQuery1.SQL.Clear;
  FormDLL.ADOQuery1.SQL.Add('select * from test');
  FormDLL.ADOQuery1.Open;
end;
initialization
  CoInitialize(nil);
finalization
  CoUnInitialize;
end.
我在一应用程序中调用该DLL,应用程序代码如下:
unit UseDLL;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ADODB,ActiveX, DB;type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;var
  Form1: TForm1;
  function ShowForm:Integer;stdcall;
  external'myforms.dll';
implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
begin
  ShowForm;//调用动态库myforms.dll中的函数
end;end.
现在的问题是,当我运行应用程序,按下应用程序中的按钮Button1显示DLL中的窗体,我再按下DLL窗体中的按钮BitBtn2,就出现以下错误代码:
Access violation at address 002f1B81 in module 'myforms.dll',read of address 00000324.
请问,我到底错在哪里?问题解决后马上给分!

解决方案 »

  1.   

    我也在找这方面的资料,不知道以下的代码能否帮到你。unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, DB, adodb, StdCtrls, DBClient, MConnect, SConnect ;type
      TForm1 = class(TForm)
        Button1: TButton;
        ADOConnection1: TADOConnection;
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.dfm}procedure DoTest(H: THandle; AConn: TADOConnection; S: string; N: Integer); cdecl; external 'project2.dll'procedure TForm1.Button1Click(Sender: TObject);
    begin
      DoTest(Application.Handle, ADOConnection1, 'Call OK', 256);
    end;end.
      

  2.   

    library Project2;uses
      SysUtils,
      Classes,
      Unit2 in 'Unit2.pas' {Form1};{$R *.res}
    exports
      DoTest;begin
    end.
      

  3.   

    unit Unit2;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, DB, ADODB, DBClient, MConnect, SConnect, Grids,
      Wwdbigrd, Wwdbgrid, ExtCtrls, DBCtrls, DBGrids;type
      TForm1 = class(TForm)
        ADOConnection1: TADOConnection;
        Memo1: TMemo;
        DataSource1: TDataSource;
        Panel1: TPanel;
        Button1: TButton;
        DBNavigator1: TDBNavigator;
        Button2: TButton;
        ADOQuery1: TADOQuery;
        DBGrid1: TDBGrid;
        procedure Button1Click(Sender: TObject);
        procedure Button2Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;procedure DoTest(H: THandle; AConn: TADOConnection; S: string; N: Integer); cdecl;var
      Form1: TForm1;implementation{$R *.dfm}procedure DoTest(H: THandle; AConn: TADOConnection; S: string; N: Integer);
    begin
      Application.Handle := H;
      with TForm1.Create(Application) do
        try
          Memo1.Lines.Append('成功调用');
          ADOConnection1 := AConn;
          Memo1.Lines.Append(ADOConnection1.ConnectionString + '-' + S + '-' + IntToStr(N));
          ShowModal;
        finally
          Free;
        end;    // with
    end;procedure TForm1.Button1Click(Sender: TObject);
    begin
      Close;
    end;procedure TForm1.Button2Click(Sender: TObject);
    begin
      with ADOQuery1 do
      begin
        ADOQuery1.Connection := ADOConnection1;
        SQL.Clear;
        SQL.Add('select * from authors');
        Open;
      end;    // with
    end;end.
      

  4.   

    引用:
    procedure TFormDLL.BitBtn2Click(Sender: TObject);
    begin
      FormDLL.ADOQuery1.SQL.Clear;
      FormDLL.ADOQuery1.SQL.Add('select * from test');
      FormDLL.ADOQuery1.Open;
    end;好像要先关闭FormDll,应该是:
    procedure TFormDLL.BitBtn2Click(Sender: TObject);
    begin
      FormDLL.ADOQuery1.Close;
      FormDLL.ADOQuery1.SQL.Clear;
      FormDLL.ADOQuery1.SQL.Add('select * from test');
      FormDLL.ADOQuery1.Open;
    end;
      

  5.   

    procedure TFormDLL.BitBtn2Click(Sender: TObject);
    begin
      FormDLL.ADOQuery1.Active:=False;
      FormDLL.ADOQuery1.SQL.Clear;
      FormDLL.ADOQuery1.SQL.Add('select * from test');
      FormDLL.ADOQuery1.Open;
    end;