I have an interface to use over DCOM technology.
All methods defined in the interface have safecall
directive.
However, in a client side, I want to reflect this object in an TObject to avoid transit with the interface each time I need read them.
For example
IMyInterface = interface(IDispatch);
procedure Set_fA(const Value: WideString); safecall;
function Get_fA: WideString; safecall;
end;
This interface is implemented by a TAutoIntfObject
, in this case the implementation keep safecall
directive
TMyAuto = class(TAutoIntfObject, IMyInterface)
private
fA : WideString;
public
procedure Set_fA(const Value: WideString); safecall;
function Get_fA: WideString; safecall;
end;
But now, with TObject If I remove safecall:
TMyObject = class(TObject, IMyInterface)
private
fA : WideString;
public
procedure Set_fA(const Value: WideString); //??
function Get_fA: WideString; //??
procedure CopyFromServer(Original: OleVariant);
end;
The compiler generates the following error: "Declaration of Set_fA differs from declaration in interface IMyObject"
I can normally use TObject with safecall, there will be any trouble if I keep this way?
There is any case where safecall makes all the difference instead of cdecl?
The reason why I'm doing this is because I want avoid transit to the server every time I need to read some TMyAuto
instance properties.
If the canonical value of your data is on the server, but you don't have to hit the server every time you want to access the value, you can cache it locally. It would look something like this:
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;
Then you have a local copy of the data, and you don't have to fetch it from the server every time.
The downside is, your data is cached. Caches can become stale (out of date) if other people are accessing the server at the same time as you, and keeping a cache in sync with the main data store has been called one of the two truly hard problems in Computer Science.
If you're not sure that the data won't be changed while you're caching it, you have two ways to manage it. First, set up a system where any changes made to the main data store get sent out to everyone who's got a cached copy so they can update their caches. This can be very complicated and involved, and is really only worth it if you have a system of a certain size and complexity.
Or, second, don't cache data that's likely to change. Just swallow the overhead as part of the cost of doing business.
Which solution you pick is up to you. Make sure you analyze things really well before deciding, though.