Simon Laws wrote:
I notice in implementing the PHP extension (yes - believe it or not I'm
nearly ready to make a patch for the next version ;-) that, given the way
that I have implemented the PHP extension there is insufficient
information
available in the SCA runtime in order to do correct type conversions when
passing messages between components. I imagine this has been raised
before
but I looked at the archive and couldn't find a relevant thread.
Imagine the scenario:
C++ Component (ComponentA) ---WireA---> PHP Component (ComponentB)
---WireB----> C++ Component (ComponentC)
Currently the build process looks at the header files described in the
component type files and generates wrappers and proxies for the C++
components. I have currently implemented the PHP Extension to use generic
wrappers and proxies, i.e. it doesn't use those generated based on the
interface descriptions, so they need to dynamically manage the type
conversions for data coming in and going out of a PHP component.
WireA.
This is OK because the C++ SCA operation object that appears at
Component B
has a set of data/types based on the generated proxy. The PHP
extension can
look at this and effect the right type conversions.
WireB
This is problematic. The dynamic PHP proxy has to generate an operation
object to pass to the the wrapper of ComponentC. The issue is that
there is,
as far as I can tell, no dynamic way of getting at the list of types that
are expected for any particular operation. There is of course a static
C++
proxy/wrapper combination that has been generated but I can't inspect
it at
runtime.
I'm not keen on generating PHP specific interface classes. PHP is a
dynamic
environment and it's a whole stack of extra files we could do without
having
to manage particularly if we have to adapt the generator for every
extension
that's constructed. Can we extend the wrapper/proxy mechanism to
encapsulate
a runtime list of required types alongside the static method descriptions
that are already generated? We would need this to work for script to
script
calls as well as for the script/C++ combination so maybe we need
something
that hangs off the interface description part of the model. I'm not that
familiar with how that part of the model is used so a little
investigation
is required.
Thoughts?
Simon
Simon,
It's an interesting issue. To explore it let's walk through the wiring
scenario you describe and assume the following:
- ComponentA (C++) -> WireA -> ComponentB (PHP) -> WireB -> ComponentC (C++)
- ComponentA (C++) passes a short int to ComponentB (PHP)
- ComponentB executes a PHP script which in turn passes a number to
ComponentC (C++)
- ComponentC expects that number to be given as a long int.
Here's what I think should happen in the runtime:
1. At the source of WireA, a generated C++ CPPServiceProxy adds to our
Operation object a Parameter of a type decided by the C++ client code: a
C++ short int, with type == ParameterType::SHORT.
2. At the end of WireA, a PHPServiceWrapper converts that parameter to
what the PHP script expects, for the sake of simplicity now I am going
to assume that it needs to convert it to a C++ std::string.
3. The PHP script executes, now passes an std::string containing a
number to the PHPServiceProxy at the source of WireB.
4. The PHPServiceProxy does not have much type info about that
std::string parameter and can only add it to the Operation object as a
std::string with type == ParameterType::STRING.
5. The CPPServiceWrapper at the end of WireB (actually the C++
ServiceWrapper generated for ComponentC) receives the std::string and
should convert it to what ComponentC expects: a long int.
The general idea is that a ServiceProxy sends what it is given (or picks
the most natural type out of the ParameterTypes that we have defined and
converts the data to it). A ServiceWrapper converts what it receives to
the type expected by the code it wraps. I think that the
CPPServiceWrapper code and the generated C++ ServiceWrappers are simply
missing the logic to convert data to what the target expects.
At the moment this limitation also prevents a C++ method
getCustomer(long customerID) to be exposed as a REST service for
example, as the generated C++ ServiceWrapper is missing the logic to
convert the customerID received in string form from the REST query
string to the expected C++ long int.
So we just need to add the missing type conversion logic to the C++
ServiceWrappers :)
Thoughts?
--
Jean-Sebastien
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]