一个是delphi的一个是api,我看书没看出他们的区别,但是以下的程序换成beginThread则会有问题。
type
  TForm1 = class(TForm)
    Button2: TButton;
    Button3: TButton;
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;var
  Form1: TForm1;implementation{$R *.dfm}
function MyThreadFunc(P:pointer):Longint;stdcall;
var
   i:integer;
   DC:HDC;
   S:string;
begin
  Result := 0;
  DC:=GetDC(Form1.Handle);
  for i:=0 to 100000 do
  begin
   S:=Inttostr(i);
   Textout(DC,10,10,Pchar(S),length(S));
  end;
  ReleaseDC(Form1.Handle,DC);
end;procedure TForm1.Button2Click(Sender: TObject);
var
  hThread:Thandle;//定义一个句柄
  ThreadID:DWord;
begin
//创建线程,同时线程函数被调用  hthread:=CreateThread(nil,0,@MyThreadfunc, nil, 0,ThreadID);
//hthread:=BeginThread(nil,0,@MyThreadfunc, nil, 0,ThreadID);
  if hThread=0 then
  begin
    messagebox(Handle,'Didn’t Create a Thread',nil,MB_OK);
  end;
end;procedure TForm1.Button3Click(Sender: TObject);
begin
  MyThreadfunc(nil);
end;

解决方案 »

  1.   

    CreateThread是window提供的API函数
    BeginThread是Delphi对CreateThread进一步的封装,内部实现时用到了CreateThreadfunction BeginThread(SecurityAttributes: Pointer; StackSize: LongWord;
      ThreadFunc: TThreadFunc; Parameter: Pointer; CreationFlags: LongWord;
      var ThreadId: LongWord): Integer;
    var
      P: PThreadRec;
    begin
      New(P);
      P.Func := ThreadFunc;
      P.Parameter := Parameter;
      IsMultiThread := TRUE;
      Result := CreateThread(SecurityAttributes, StackSize, @ThreadWrapper, P,
        CreationFlags, ThreadID);
    end;
      

  2.   

    这个我看过,但是看不出为什么上面那个程序换成beginthread就会有问题,beginthread将ThreadFunc打包,原来的self指针换成Pointer类型,能给说详细点么?谢谢
      

  3.   

    。。真恶心,我忘记stdcall的影响了
      

  4.   

    BeginThread主要比CreateThread多做了两件事:
    一件是设置了IsMultiThread := TRUE;
    这个全局变量在很多地方要用到,比如分配内存、COM应用时
    另一件是在ThreadWrapper里加入了异常保护你的那段代码出错,是因为没有调用EndThreadfunction MyThreadFunc(P:pointer):Longint;stdcall;
    var
       i:integer;
       DC:HDC;
       S:string;
    begin
      Result := 0;
      DC:=GetDC(Form1.Handle);
      for i:=0 to 100000 do
      begin
       S:=Inttostr(i);
       Textout(DC,10,10,Pchar(S),length(S));
      end;
      ReleaseDC(Form1.Handle,DC);
      EndThread(0);
    end;procedure TForm1.Button1Click(Sender: TObject);
    var
      hThread:Thandle;//定义一个句柄
      ThreadID:DWord;
    begin
    //创建线程,同时线程函数被调用  hthread:=BeginThread(nil,0,@MyThreadfunc, nil,0,ThreadID);
      if hThread=0 then
      begin
        messagebox(Handle,'Didn’t Create a Thread',nil,MB_OK);
      end;
    end;
      

  5.   

    的确是stdcall的问题,不过加了EndThread(0);也可以解决报错问题
      

  6.   

    TParentBase=class
      public
        procedure DoAnyThing;
      end;  TChildBase=class
      public
        procedure DoAnyThing;
      end;  TParent=class(TParentBase)
      private
        FChild : TChildBase;
      end;  TChild=class(TChildBase)
      private
        FParent : TParentBase;
      end;
      

  7.   

    IParent=Interface
        procedure DoAnyThing;
      end;  IChild=Interface
        procedure DoAnyThing;
      end;  TParent=class(TObject,IParent)
      private
        FChild : IChild;
      end;  TChild=class(TObject,IChild)
      private
        FParent : IParent;
      end;
      

  8.   

    把MyThreadFunc作为BeginThread的参数有两个问题
      1.P参数无效(MyThreadFunc会从栈顶获取,而实际上在EAX中传递过来)
      2.函数无法正确返回(MyThreadFunc把栈顶的返回地址当成P参数了,而取了下一个不确定的元素作为返回地址)
    所以在MyThreadFunc中加EndThread只是让线程在函数返回前结束执行,并不能解决第一个问题——而这可能会带来严重的错误,因为MyThreadFunc里P参数是一个指向代码段内存的地址(ThreadWrapper函数的执行体中某位置)。
      另外看起来调用EndThread会造成BeginThread中分配的PThreadRec内存泄漏。