本人刚学dll,大家帮忙看看。
program Project1;uses
  Forms, Dialogs, Classes,
  Unit1 in 'Unit1.pas' {Form1};function Login(AHandle: THandle; ACaption: ShortString): Boolean; external 'LoginDll.dll' name 'Login';
function GetUserName:PChar; external 'LoginDll.dll' name 'GetUserName';{$R *.res}
var
  a:PChar;begin
  a:='abc';
  Application.Initialize;
  if Login(Application.Handle, a) then begin
    showmessage('成功');
    a:=GetUserName;    // 这有问题不能编译。注释掉可以编译
  end
  else begin
    showmessage('失败');
    Application.Terminate;
  end;  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.
library LoginDll;
uses
  SysUtils,
  Classes,
  LoginFrm in 'LoginFrm.pas' {LogInForm};{$R *.res}exports
  Login,
  GetUserName,
  GetPassword,
  GetProject;
begin
end.unit LoginFrm;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls, jpeg, IniFiles;type
  TLogInForm = class(TForm)
    btnOk: TButton;
    btnCancel: TButton;
    Image1: TImage;
    Label2: TLabel;
    lblUserId: TLabel;
    Label1: TLabel;
    lblProjCode: TLabel;
    EditUserId: TEdit;
    EditPassWd: TEdit;
    EditProjCode: TEdit;
    procedure btnOkClick(Sender: TObject);
    procedure FormKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;  function Login(AHandle: THandle; ACaption: String): boolean; stdcall;
  function GetUserName:PChar; stdcall;
  function GetPassword:PChar; stdcall;
  function GetProject :PChar; stdcall;var
  Check: boolean;
  FUserName:PChar;
  FPassword:PChar;
  FProject :PChar;implementation{$R *.dfm}procedure TLogInForm.btnOkClick(Sender: TObject);
begin
  if (EditUserId.text='') then begin
    MessageDlg('用户代码不能为空!', mtError, [mbOk], 0);
    editUserID.SetFocus;
    Exit;
  end
  else if (EditPassWd.text='') then begin
    MessageDlg('用户密码不能为空!', mtError, [mbOk], 0);
    editPassWd.SetFocus;
    Exit;
  end
  else if (EditProjCode.text='') then begin
    MessageDlg('项目代码不能为空!', mtError, [mbOk], 0);
    editProjCode.SetFocus;
    Exit;
  end
  else begin
    FUserName:=PCHAR(editUserid.Text);
    FPassword:=PCHAR(EditPassWd.Text);
    FProject:=PCHAR(EditProjcode.text);
    Check:=True;
    ModalResult:=mrOK;
  end;
end;procedure TLogInForm.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  case key of
    VK_RETURN : btnOkClick(self);
    VK_ESCAPE : begin
      ModalResult:=mrCancel;
    end;
  end;
end;function Login(AHandle: THandle; ACaption: String): boolean;
var
  LogInForm: TLogInForm;
begin
   Check := False;
   Application.Handle := AHandle;
   LoginForm := TLoginForm.Create(Application);
   try
     LoginForm.Caption := ACaption;  // 这也有问题,标题为乱码
     LoginForm.ShowModal;
     //返回给调用本dll的应用程序判断
     Result:=Check;
   finally
     LoginForm.Free;
   end;
end;procedure TLogInForm.FormCreate(Sender: TObject);
var
  IniFile:TIniFile;
begin
  IniFile:=TIniFile.Create(ExtractFilePath(Application.ExeName)+'Login.ini');
  EditUserID.Text:=IniFile.ReadString('LogInfo', 'userID', '');
  EditProjCode.Text:=IniFile.ReadString('LogInfo', 'projectID', '');
  IniFile.Free;
end;function GetUserName:PChar;
begin
  Result:=FUserName;
end;function GetPassword:Pchar;
begin
  Result:=FPassword;
end;function GetProject:PChar;
begin
  Result:=FProject;
end;end.

解决方案 »

  1.   

    靠,a:=GetUserName
    能这么赋值吗?UP一下
      

  2.   

    function GetUserName:PChar;
    begin
      getmem(result,length(fusername));
      strpcopy(result,fusername);
    //  Result:=FUserName;
    end;
      

  3.   

    先给指针分配内存,用StrCopy复制
      

  4.   

    wwwxuhong(用delphi的) 还是不行
      

  5.   

    FUserName和GetUserName为ShortString也不行
      

  6.   


    把GetUserName函数改一下
    funcation GetUserName:PChar;stdcall;
    begin
      ...
    end;
      

  7.   

    同意 ehom(?!) !!var strTemp : array[0..10] of char; //可以用动态数据....StrCopy(xxx{你的参数PChar型}, strTemp) ;
    另外:
    function Login(AHandle: THandle; ACaption: String): boolean;
    var
      LogInForm: TLogInForm;
    begin
       Check := False;
       Application.Handle := AHandle;
       LoginForm := TLoginForm.Create(Application);
       try
         LoginForm.Caption := ACaption;  // 这也有问题,标题为乱码
         LoginForm.ShowModal;
         //返回给调用本dll的应用程序判断
         Result:=Check;
       finally
         LoginForm.Free;
       end;
    end;
    你的ACaption不可以用String的,那是Delphi解释的,你要用Windows标准的字符串,或者用PChar
      

  8.   

    function GetUserName:PChar;
    begin
      GetMem(Result, Length(FUserName));
      StrCopy(Result, FUserName);
    end;这样也不行啊
      

  9.   

    不可以的!  Size := Edit1.GetTextLen;       {Get length of string in Edit1}
      Inc(Size);                      {Add room for null character}
      GetMem(Buffer, Size);           {Creates Buffer dynamic variable}
      Edit1.GetTextBuf(Buffer,Size);  {Puts Edit1.Text into Buffer}
      Edit2.Text := StrPas(Buffer);   {Converts Buffer to a Pascal-style string}
      FreeMem(Buffer, Size);{Frees memory allocated to Buffer}
      

  10.   

    这是帮助里的说明!注意:Inc(Size);   {Add room for null character}而且你的
    LoginForm.Caption := ACaption;
    的ACaption是String的,所以会有乱码因为Dll是不认String的
      

  11.   

    dll支持shortstring,可是也不行。
      

  12.   

    MSDN上对Dll的字符型的建议是采用标准的C的字符类型,你试试吧
      

  13.   

    上面的这些都说的不对
    ,你应该在Uses语句中加上Sharemem,工程中的Uses中叶加上,并放在第一个就行了,因为你传的是String型,这是Delphi的解释
    { 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. }
      

  14.   

    将program Project1中的:
    function Login(AHandle: THandle; ACaption: ShortString): Boolean; external 'LoginDll.dll' name 'Login';
    function GetUserName:PChar; external 'LoginDll.dll' name 'GetUserName';改为:
    function Login(AHandle: THandle; ACaption: ShortString): Boolean;stdcall; external 'LoginDll.dll' name 'Login';
    function GetUserName:PChar; stdcall;external 'LoginDll.dll' name 'GetUserName';
    两个都加上stdcall
      

  15.   

    写及调用DLL要注意的问题:
    1、函数的参数传递问题,编写及调用都要加stdcall;
    2、尽量避免使用String类型参数,在使用到时,要在编写调用的单中加入ShareMem引用。
    第2个问题是一个头痛的问题,我用的是TStringList参数,怎么也不能正常调用,现在正在
    找解决方法。
      

  16.   

    function Login(AHandle: THandle; ACaption: String): boolean; stdcall;
      function GetUserName:PChar; stdcall;
      function GetPassword:PChar; stdcall;
      function GetProject :PChar; stdcall;这四句去掉后面的stdcall;
      

  17.   

    用前先分配一下内存,STRING型数据可能会出错
    function Login(AHandle: THandle; ACaption: Pchar): boolean;
    var
      LogInForm: TLogInForm;
    begin
       Getmem(ACaption,30);
       Check := False;
       Application.Handle := AHandle;
       LoginForm := TLoginForm.Create(Application);
       try
         LoginForm.Caption := string(ACaption);  // 这也有问题,标题为乱码
         LoginForm.ShowModal;
         //返回给调用本dll的应用程序判断
         Result:=Check;
       finally
         LoginForm.Free;
         freemem(ACaption,30);
       end;
    end;
      

  18.   

    返回值用string就不会有这么多问题了!