0

我有一个可以通过 DCOM 技术使用的界面。
接口中定义的所有方法都有safecall指令。
但是,在客户端,我想将此对象反映在 TObject 中,以避免每次需要读取它们时与接口进行传输。

例如

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

该接口由 a 实现TAutoIntfObject,在本例中为实现 keepsafecall指令

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 中的声明不同”

我可以正常使用TObject和safecall,如果我保持这种方式会有什么问题吗?
在任何情况下,safecall 会比 cdecl 更重要吗?

我这样做的原因是因为我想避免每次需要读取一些TMyAuto实例属性时都传输到服务器。

4

2 回答 2

2

Go ahead and put safecall back on your methods. The interface requires it. The interface will also require that you implement the rest of the methods introduced by IDispatch since TObject doesn't implement them itself.

Safecall and cdecl are entirely different calling conventions; they're never interchangeable. They differ in who cleans up the stack, and they differ in how errors are transmitted between caller and receiver. The interface specifies one, so you don't get to choose something different when you implement it.

于 2013-07-26T22:19:28.953 回答
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;

然后你就有了数据的本地副本,你不必每次都从服务器获取它。

缺点是,您的数据被缓存。如果其他人与您同时访问服务器,缓存可能会变得陈旧(过时),并且保持缓存与主数据存储同步被称为计算机科学中两个真正困难的问题之一。

如果您不确定在缓存数据时不会更改数据,您有两种方法来管理它。首先,建立一个系统,将对主数据存储所做的任何更改发送给拥有缓存副本的每个人,以便他们可以更新他们的缓存。这可能非常复杂和复杂,并且只有当您拥有一定规模和复杂性的系统时才真正值得。

或者,第二,不要缓存可能改变的数据。只需将开销作为开展业务成本的一部分即可。

您选择哪种解决方案取决于您。不过,请确保在做出决定之前对事情进行了很好的分析。

于 2013-07-26T20:32:10.963 回答