procedure TfrmMain.N6Click(Sender: TObject);
var
  PassWord : String;
begin
//更改密码
  ADODB549.GetPasswordWithQuery(PassWord,'content','PassWord','item','DinFinDic',q1);
  ADODB549.ChangePasswordWithQuery(Pass,'content','DinFinDic',q1);
end;///////////////////////////
//下面是函数原型
function GetPasswordWithQuery( var   PassWord      : String;
                               const PasswordField : String;
                               const TableName     : String;
                               Query : TADOQuery ) : Boolean; overload;
var
  SQLString : String;
begin
  Result := False;
  SQLString := 'select * from ' + TableName;
  if not OpenSQL(SQLString, Query) then Exit;
  if Query.IsEmpty then Exit;
  PassWord := Query.FieldByName(PasswordField).AsString;
  Result := True;
end;
function GetPasswordWithQuery( var   PassWord      : String;
                               const PasswordField : String;
                               const UserName      : String;
                               const UserNameField : String;
                               const TableName     : String;
                               Query : TADOQuery ) : Boolean; overload;
var
  SQLString : String;
begin
  Result := False;
  SQLString := 'select * from ' + TableName + ' where ' + UserNameField + '=''' + UserName + '''';
  if not OpenSQL(SQLString, Query) then Exit;
  if Query.IsEmpty then Exit;
  PassWord := Query.FieldByName(PasswordField).AsString;
  Result := True;
end;

解决方案 »

  1.   

    function  ChangePasswordWithQuery( Password : String; PasswordFieldName : String;
                                       TableName : String;
                                       ADOQuery : TADOQuery ) : Boolean; overload;
    //Change Password and Write Back to Table
    //With No UserName
    //9:25 2003-10-15
    var
      NewPassword : String;
      SQLString   : String;
    begin
      Result := False;
      NewPassword := DLL549.ChangePassword( Password );
      SQLString   := 'update ' + TableName + ' set ' + PasswordFieldName + '=''' + NewPassword + '''' + 'where ' + PasswordFieldName + '=''' + Password + '''';
      if not ExeSQL( SQLString, ADOQuery ) then Exit;
      Result := True;
    end;
    function  ChangePasswordWithQuery( const UserName : String;    Password : String;
                                       UserNameFieldName : String; PasswordFieldName : String;
                                       TableName : String;
                                       ADOQuery : TADOQuery ) : Boolean; overload;
    //Change Password and Write Back to Table
    //With UserName
    //9:25 2003-10-15
    var
      NewPassword : String;
      SQLString   : String;
    begin
      Result := False;
      NewPassword := DLL549.ChangePassword( Password );
      SQLString   := 'update ' + TableName + ' set ' + PasswordFieldName + '=''' + NewPassword + '''';
      SQLString   := SQLString + 'where ' + PasswordFieldName + '=''' + Password + '''';
      SQLString   := SQLString + ' and ' + UserNameFieldName + '=''' + UserName + '''';
      if not ExeSQL( SQLString, ADOQuery ) then Exit;
      Result := True;
    end;
      

  2.   

    奇怪的是:
    procedure TfrmMain.N6Click(Sender: TObject);
    var
      PassWord : String;
      Pass : String;
    begin
    //更改密码
      ADODB549.GetPasswordWithQuery(PassWord,'content','PassWord','item','DinFinDic',q1);
      Pass := PassWord;
      ADODB549.ChangePasswordWithQuery(Pass,'content','DinFinDic',q1);
    end;///////////////////////
    //这样没有任何错误,呵呵。
      

  3.   

    是外部变量的问题还是dll的问题?
    呵呵,我真的晕了。
    单独执行
    ADODB549.GetPasswordWithQuery(PassWord,'content','PassWord','item','DinFinDic',q1);或者
    ADODB549.ChangePasswordWithQuery(Pass,'content','DinFinDic',q1);
    都没有AV错误。
      

  4.   

    两种情况
    程序运行结果完全正确。所以大家不要怀疑代码的逻辑问题。个人认为:出现AV错误的原因应该是外部变量和DLL之间的冲突。
      

  5.   

    简化一下:
    function a (var a : String): Boolean;
    begin
      ...
    end;function b (c : String) : Boolean;
    begin
      ...//调用一个dll,用到c
    end;procedure AV();//有av错误
    var
      x : String;
    begin
      a(x);
      b(x); 
    end;procedure NoAV();//没有av错误
    var
      x : String;
      y : String;
    begin
      a(x);
      y := x;
      b(y); 
    end;
      

  6.   

    补充:
    运行的时候没有AV错误,在程序关闭的时候才出现AV错误的。
      

  7.   

    更正:
    procedure NoAV();//没有av错误
    var
      x : String;
      y : String;
    begin
      a(x);
      y := 'aaa';//不能引用x
      b(y); 
    end;
    ///////////////////////////////////
    现在下面这个也出错误了
    procedure TfrmMain.N6Click(Sender: TObject);
    var
      PassWord : String;
      Pass : String;
    begin
    //更改密码
      ADODB549.GetPasswordWithQuery(PassWord,'content','PassWord','item','DinFinDic',q1);
      Pass := PassWord;
      ADODB549.ChangePasswordWithQuery(Pass,'content','DinFinDic',q1);
    end;//同样的AV错误。
      

  8.   

    不知道你DLL里的东西怎么写的,也许不能这么传递参数;
      

  9.   

    //DLL中的函数
    function ChangePassword ( Password : String;
                              Title    : String = '更改密码';
                              Caption  : String = '请输入密码信息';
                              OldPass  : String = '原始密码';
                              NewPass  : String = '更新密码';
                              ConfPass : String = '确认密码'
                             ) : String; stdcall;
    var
      Change : TfrmChangePassword;
    begin
      Result := Password;
      try
        PasswordString := Password;
        Change := TfrmChangePassword.Create( nil );
        Change.Caption := Title;
        Change.GroupBox1.Caption := Caption;
        Change.Label1.Caption := OldPass;
        Change.Label2.Caption := NewPass;
        Change.Label3.Caption := ConfPass;
        Change.ShowModal;
        Result := PasswordString;//过程很简单:先判断旧密码是否正确,然后判断新密码是否一致,最后决定是否保存给PasswordString。所以就没写
      finally
        Change.Free;
      end;
    end;
      

  10.   

    发现原因了,呵呵,低级错误。dll没有引用ShareMem很久以前做的东西了,呵呵,当时没出现错误就没加这个单元。朋友们引以为戒。