如下是DELPHI7中的代码,运行完美通过。unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, OleServer, PCDLRN_TLB, StdCtrls, ActiveX, ComCtrls, ComObj;type
tloadpc=class(tthread)
protected
procedure execute;override;
end;
TForm1 = class(TForm)
btn1: TButton;
procedure btn1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;
FAPP:IApplication;implementation
{$R *.dfm}
procedure tloadpc.execute;
begin
inherited;
FAPP:=CreateOleObject('PCDLRN.Application') as IApplication;
end;procedure TForm1.btn1Click(Sender: TObject);
begin
tloadpc.Create(false);
end;initialization
CoInitializeEx(nil,0);
finalization
CoUnInitialize;
end.但是在DELPHI2009是运行却是通不过的,因为DELPHI2009中竟然无法在单元初始化处为线程申请套间,郁闷……,所有代码改为如下:var
Form1: TForm1;
FAPP:IApplication;implementation
{$R *.dfm}
procedure tloadpc.execute;
begin
inherited;
CoInitializeEx(nil,0);
FAPP:=CreateOleObject('PCDLRN.Application') as IApplication;
CoUnInitialize;
end;procedure TForm1.btn1Click(Sender: TObject);
begin
tloadpc.Create(false);
end;但此时问题就出现了,在D7中线程结束后PCDLRN.EXE进程是不消失的,但是在DELPHI2009中随着线程EXECUTE过程的完毕PCDLRN.EXE进程也消失了,也就意味着后续无法再对该COM进行操作了,DELPHI2009做了个什么呀……,请大家帮忙,谢谢!
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, OleServer, PCDLRN_TLB, StdCtrls, ActiveX, ComCtrls, ComObj;type
tloadpc=class(tthread)
protected
procedure execute;override;
end;
TForm1 = class(TForm)
btn1: TButton;
procedure btn1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;
FAPP:IApplication;implementation
{$R *.dfm}
procedure tloadpc.execute;
begin
inherited;
FAPP:=CreateOleObject('PCDLRN.Application') as IApplication;
end;procedure TForm1.btn1Click(Sender: TObject);
begin
tloadpc.Create(false);
end;initialization
CoInitializeEx(nil,0);
finalization
CoUnInitialize;
end.但是在DELPHI2009是运行却是通不过的,因为DELPHI2009中竟然无法在单元初始化处为线程申请套间,郁闷……,所有代码改为如下:var
Form1: TForm1;
FAPP:IApplication;implementation
{$R *.dfm}
procedure tloadpc.execute;
begin
inherited;
CoInitializeEx(nil,0);
FAPP:=CreateOleObject('PCDLRN.Application') as IApplication;
CoUnInitialize;
end;procedure TForm1.btn1Click(Sender: TObject);
begin
tloadpc.Create(false);
end;但此时问题就出现了,在D7中线程结束后PCDLRN.EXE进程是不消失的,但是在DELPHI2009中随着线程EXECUTE过程的完毕PCDLRN.EXE进程也消失了,也就意味着后续无法再对该COM进行操作了,DELPHI2009做了个什么呀……,请大家帮忙,谢谢!
意思是线程结束后即释放。
...
procedure TMyComThread.Execute;
begin
CoInitializeEx(Nil, COINIT_MULTITHREADED);
Excel := CreateOleObject('Excel.Application');
CoUninitialize;
end;
...
initialization
if CoInitializeEx(Nil, COINIT_MULTITHREADED) = RPC_E_CHANGED_MODE then begin
CoUninitialize;
CoInitializeEx(Nil, COINIT_MULTITHREADED);
end;finalization
CoUninitialize;
end.
var
{$IF DEFINED(CLR)}
SB: System.Text.StringBuilder;
P: Integer;
C: Char;
{$ELSE}
P: PChar;
ModuleName: array[0..255] of Char;
{$IFEND}
begin
inherited Create(AOwner);
if not IsLibrary then
FNeedToUninitialize := Succeeded(OleInitialize(nil));//问题应该是出在这里
if not Assigned(Classes.ApplicationHandleException) then
DELPHI2009环境下,在单元的INITIALIZATION处调用COINITIALIZEEX返回是失败的
CODE GEAR程序员考虑的太多而且太仔细,所以导致了多线程操作COM时无法在主线程内为其申请线程套间,问题就是出现在僵哥所提的那一点上问题原因解释:OleInitialize在内部调用CoInitializeEx来初始化COM库。因为OLE操作不是线程安全的,所以OleInitialize指定运行模式为single-thread apartment修改办法:
将OleInitialize改为CoInitializeEx(nil,0)在DESTROY实现部分将OleUnInitialize改为CoUnInitialize问题进一步分析:其实CODE GEAR的初衷是其常好的,他们也想模仿微软的C#,实现多线程操作COM时的程序员不参与性,可惜用错了东西,如果您要自行进行申请套间,还有另一种修改方案,那就是将这些所谓为程序省事的部分(CREATE和DESTROY实现内的OleInitialize操作部分)删掉。另外多插一句,CODE GEAR官方网站最新的DELPHI版本安装后在安装目录的SOURCE文件内只有一个dUnit文件夹,其它的都没有了(像database,Win32...),不知道CODE GEAR做这些一初是怎么想的。再次感谢大家对该问题的关心。