Jeff,
Thank you for comments and example (in my 3.14.9 version,
it is located in base/src/makeBaseApp/top/caServerApp/exPV.cc).
I need to learn about the application types. In any
case, the plan is not to change the GDD primitive types and to use a typed
service for PVs with the predefined types: array of aitInt8s.
Actually, the src/makeBaseApp/top/caServerApp/
directory contains
another interesting example exVectorPV.cc (with array of aitFloat64).
Nikolay
From: Jeff Hill
[mailto:[email protected]]
Sent: Friday, June 26, 2009 11:41 AM
To: Malitsky, Nikolay D; [email protected]
Subject: RE: Channel Access Portable Server,passing by pointer in
read/write methods
Nikolay,
For the write implementation
what you have will work but you are allowing the client to change the GDD
primitive type and application type structure of your service’s
representation – which may or may not be appropriate in your situation.
You end up with an un-typed service which could cause less predictable
behavior. The client could for example change, using one write, a double value
surrounded by lots of meta data into the string value “off” with no
metadata for example.
For your read implementation the
primary concern might be that the service wouldn’t be looking at some of
the details of the read request from the client. In particular, the destination
GDD comes preformatted with all of the application types that the client is
fetching (i.e. all of the GDD application types in a CA DBR_XXXX – say
DBR_GRAPHIC_DOUBLE), but your code snippet is substituting instead what the
service is storing. Maybe this is ok as long as a superset of all of the
application types is always provided (where the superset is modal depending on
the DBR_XXXX data model for the value type of string, float, or enum). The
client’s request would be rejected for example if the destination value
has primitive type double and the substituted value is a string with value
“off”. What you have suggested might be ok as long as you
don’t mind leaving the error checking to the server. The server does do
the necessary primitive type conversion checking of the response. If any of the
application types are missing for the clients DBR_XXX type then the
client’s read request is rejected.
The code in
base/src/makeBaseApp/templates/caServerApp/exPV.cc shows another way to
implement a read using a dispatch table for each of the applications types. I
don’t claim that it’s the proper way to structure a service, but
perhaps it can provide some contrast.
The GDD library also as I recall
supports GDD container to GDD container assignment which would be another way
to implement the read.
Jeff
Hello,
I am considering the Channel Access Portable Server for supporting the
C++ middle layer servers.
The associated PVs will maintain one-dimensional arrays of characters.
Their lengths can be
significant. So, passing by pointer in read/write methods would be
a preferable way. The ‘write’ case
looks straightforward (as described in the tutorial, p.35):
class my PV : public casPV {
….
gdd* pValue;
};
caStatus myPV::write(const casCtx& ctx, gdd &value){
…
pValue->unreference();
pValue = &value;
pValue->reference();
…
}
The ‘read’ case looks trickier (Probably, because it is not
explained).
In short, CORBA addresses such case by using the additional wrappers,
e.g. gdd_var objects,
in the ‘read’ method. However, the signature of this method
is already defined by the basis
class casPV. Fortunately, it seems we can still use the gdd-based
approach using another
mechanism, the pv-associated destructor, e.g. myPVReadDestructor:
caStatus myPV::read(const casCtx& ctx, gdd &value){
…
value.putRef(pValue->dataPointer(), new myPVReadDestructor(pValue));
pValue->reference();
}
where :
myPVReadDestructor::run(…){
pValue->unreference();
}
Any comments and suggestions about a better solution.
Thank you,
Nikolay