2013-07-26 42 views
0

我有一個接口使用DCOM技術。
接口中定義的所有方法都有safecall指令。
但是,在客戶端,我想在TObject中反映這個對象,以避免每次需要閱讀它時都使用該接口。接口safecall,實現不safecall

例如

IMyInterface = interface(IDispatch); 
    procedure Set_fA(const Value: WideString); safecall; 
    function Get_fA: WideString; safecall; 
end; 

該接口由一個TAutoIntfObject實現的,在這種情況下,實施保持safecall指令

TMyAuto = class(TAutoIntfObject, IMyInterface) 
private 
    fA : WideString; 
public 
    procedure Set_fA(const Value: WideString); safecall; 
    function Get_fA: WideString; safecall; 
end; 

但是現在,隨着TObject的如果我刪除safecall:

TMyObject = class(TObject, IMyInterface) 
private 
    fA : WideString; 
public 
    procedure Set_fA(const Value: WideString); //?? 
    function Get_fA: WideString; //?? 
    procedure CopyFromServer(Original: OleVariant); 
end; 

編譯器生成以下錯誤: 「Set_fA的聲明與接口IMyObject中的聲明不同」

我可以正常使用帶safecall的TObject,如果我保持這種方式會有什麼麻煩嗎?
有任何情況下,safecall使所有的差異,而不是cdecl?

我這樣做的原因是因爲我想避免每次需要讀取TMyAuto實例屬性時轉移到服務器。

+0

TMyObject不執行IDispatch –

回答

2

如果數據的規範值存在於服務器上,但每次訪問該值時都不必訪問服務器,則可以在本地緩存該值。它看起來像這樣:

TMyObject = class(TObject) 
private 
    fServerInterface: IMyInterface; 
    fDataLoaded: boolean; 

    //cached data 
    fA : WideString; 
    procedure LoadAllData; 
public 
    procedure Set_fA(const Value: WideString); 
    function Get_fA: WideString; 
end; 

function TMyObject.Get_fA: WideString; 
begin 
    if not fDataLoaded then 
     LoadAllData; 
    result := fA;   
end; 

procedure TMyObject.Set_fA(const Value: WideString); 
begin 
    fServerInterface.Set_fA(value); 
    fA := value; 
end; 

procedure TMyObject.LoadAllData; 
begin 
    fA := fServerInterface.Get_fA; 
    fDataLoaded := true; 
end; 

然後你有一個本地數據副本,你不必每次都從服務器獲取它。

不足的是,您的數據被緩存。如果其他人與您同時訪問服務器,並且保持緩存與主數據存儲同步,則緩存可能變爲陳舊(過期),這被稱爲計算機科學中兩個真正困難的問題之一。

如果您不確定在緩存數據時不會更改數據,則有兩種方法可以對其進行管理。首先,建立一個系統,將對主數據存儲所做的任何更改發送給每個擁有緩存副本的人員,以便他們可以更新緩存。這可能非常複雜並且涉及到,如果您擁有一定規模和複雜性的系統,那纔是真正值得的。

或者,第二,不要緩存可能會改變的數據。只需將開銷作爲開展業務的一部分。

您選擇哪種解決方案取決於您。儘管如此,在確定之前確保你真的分析得很好。

+0

在這種情況下,你有什麼建議?每次我需要讀取接口屬性時如何避免傳輸到服務器? – EProgrammerNotFound

+0

@MatheusFreitas:好的。我重寫了我的答案以解決您的疑慮。 –

+0

我想實現接口以確保所有方法都已實現,但因爲它需要安全調用,所以我想知道是否會給我帶來麻煩 – EProgrammerNotFound

2

繼續並將safecall重新放回您的方法。界面需要它。該界面還將要求您實施IDispatch引入的其餘方法,因爲TObject本身不實現它們。

Safecall和cdecl是完全不同的調用約定;他們永遠不可互換。它們在清理堆棧方面有所不同,並且它們在如何在呼叫者和接收者之間傳輸錯誤方面有所不同。該接口指定了一個接口,因此在實現它時不會選擇不同的東西。