程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> Delphi接口編程的兩大陷阱(2)

Delphi接口編程的兩大陷阱(2)

編輯:Delphi

function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;

每次都要實現這三個方法是比較麻煩的,而且更重要的是,我不知道Delphi什麼時候用以及怎麼用這三個方法?所以我也不知道怎麼實現這三個方法。

如果不想自己實現這三個方法,你可以使用TComponent。因為TComponent已經實現了這三個方法,所以可以從它繼承,就不用實現這三個方法了。

這樣就可以放心使用了嗎?答案是否定的。因為Delphi在你把接口變量置為nil時偷偷的(因為很出乎我的意料)調用了_Release。

function _IntfClear(var Dest: IInterface): Pointer;
var
P: Pointer;
begin
Result := @Dest;
if Dest <> nil then
begin
P := Pointer(Dest);
Pointer(Dest) := nil;
IInterface(P)._Release;
end;
end;

而_Release時又做了什麼呢?

function TComponent._Release: Integer;
begin
if FVCLComObject = nil then
Result := -1 // -1 indicates no reference counting is taking place
else
Result := IVCLComObject(FVCLComObject)._Release;
end;

不是Com對象的話,就什麼也沒作。我們作的不是Com對象,是不是就沒有任何問題了呢?答案依然是否定的,考慮如下情況:

OBJ2 := TC2.Create;
try
Intf1 := OBJ2;
Intf1.DO;
Finally
OBJ2.Free;
Intf1 := nil;
End;

會怎麼樣呢?會出非法地址訪問錯誤。為什麼?上面說過把接口引用設為nil時,會調用_IntfClear,而_IntfClear又會調用對象的_Release,而這時這個對象已經釋放了,自然就出非法地址訪問錯誤啦。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved