线程定义如下:
procedure AccessLog(P:Pointer);
var
  Name : String;
begin
  Name := String(P);
   .
   .
   .
end;
调用的方式
var
Name : String;Name := 'File';
hThread := BeginThread(nil, 0, @AccessLog, @Name, 0, ThID);这种方式,发现在线程中取出来的Name的值是一串很长的乱码?那么应该怎么样正确取出来呢?

解决方案 »

  1.   

    procedure AccessLog(P:Pointer); stdcall; //加入stdcall 应该就可以了
    var
      Name : String;
    begin
      Name := String(P);
       .
       .
       .
    end;
      

  2.   

    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;type
      TForm1 = class(TForm)
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
     Form1: TForm1;
    implementation
    procedure AccessLog(P:Pointer); stdcall; //加入stdcall 应该就可以了
    var
      sName, tmpStr : String;
    begin
      sName := String(p^);
      tmpStr := sName;
    end;
    {$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
    var
      ThID: Cardinal;
      name: String;
    begin
      name := 'File';
      CreateThread(nil, 0, @AccessLog, @name, 0, ThID);
      Sleep(30);
    end;end.
    // 首先你的这个Name := String(P); 是不对的
    //Sleep(30); 加入这句的主要原因是避免线没有来得及运行
    //name 就被释放了, 所以造成线程访问出错!
    //要不你就把name 设置为全局变量或者类的私有成员也可
      

  3.   

    sName := String(p^);
    这一步直接报错啊。
      

  4.   

    //Sleep(30); 加入这句的主要原因是避免线没有来得及运行
    //name 就被释放了, 所以造成线程访问出错!
    上面这两句不是得很清楚了吗? 如果报错就是name 被释放掉了;
    你可以加大点等待时间: Sleep(500); 
    要不然 按照下面的来做就可以了
    //要不你就把name 设置为全局变量或者类的私有成员也可
      

  5.   

    我贴出来的代码只是整个程序的一部分,其实这个线程会启动多个,所以要传入不同的起始参数。我把Name设置为类的私有成员,在调用sName:=String(P^)的时候也会出错从而退出整个退出线程。同时我也把Sleep的时间加大了,结果还是一样。
      

  6.   

    你声明为全局变量就根本不用使用Sleep就可以了! 
    我上面的代码测试一点问题都没有啊! 要不楼主
    贴完的代码我看看.
      

  7.   

    其实这个线程会启动多个, 在调用sName:=String(P^)的时候也会出错从而退出整个退出线程
    这个问题是线程同步问题了. 定义个临界区吧.
      

  8.   

    找到原因了,用BeginThread就无法取参数,用CreateThread就可以。寒~~~~~