Quantcast

Why does a python COM server return different data to VBA and Python clients?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Why does a python COM server return different data to VBA and Python clients?

jeffwelch
My apologies to the list about my earlier question that was in html. My webmail is supposed to default to plain text but clearly did not.

I am trying to write a Python server that will be used by a C++ client. It has taken me quite a while longer than I expected. I have been through the archives and that helped me get to where I am. Many thanks to all those who support these packages.

I am using Python 2.5.1 as it is required by some vendor equipment that I must use.

One of the reasons it took me a while to get this going was that I was trying to test it in Python. Once I switched to testing it in VBA then I made much faster progress.

For demonstration purposes I used the Pippo test in the 'win32com\test' directory. I modified the testpippo.py by adding some code at the start of the testLeaks method. I added the 4 lines:

        in1 = 15
        inout1 = 99
        hr= self.object.Method3( in1, inout1)
        print hr, "retval = %d inout1 = %d"%(hr[0], hr[1])


The printed line was "(0, -31) retval = 0 inout1 = -31".


I get "retval = -41 inout1= -31"  if I execute the VBA code:

Sub TestPippo()
    Dim obj As Pippo
    Dim in1 As Long
    Dim inout1 As Long

    Set obj = CreateObject("Python.Test.Pippo")
    in1 = 1
    inout1 = 2
    retval = obj.Method3(in1, inout1)
    MsgBox ("retval = " & retval & " inout1 = " & inout1)
   
End Sub


Is there a way to call the same Python Server Method, Method3, so that both Python and VBA receive the same return data?

Regards,
j
_______________________________________________
python-win32 mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/python-win32
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Why does a python COM server return different data to VBA and Python clients?

Mark Hammond-4
On 10/04/2012 3:40 AM, [hidden email] wrote:

> My apologies to the list about my earlier question that was in html. My webmail is supposed to default to plain text but clearly did not.
>
> I am trying to write a Python server that will be used by a C++ client. It has taken me quite a while longer than I expected. I have been through the archives and that helped me get to where I am. Many thanks to all those who support these packages.
>
> I am using Python 2.5.1 as it is required by some vendor equipment that I must use.
>
> One of the reasons it took me a while to get this going was that I was trying to test it in Python. Once I switched to testing it in VBA then I made much faster progress.
>
> For demonstration purposes I used the Pippo test in the 'win32com\test' directory. I modified the testpippo.py by adding some code at the start of the testLeaks method. I added the 4 lines:
>
>          in1 = 15
>          inout1 = 99
>          hr= self.object.Method3( in1, inout1)
>          print hr, "retval = %d inout1 = %d"%(hr[0], hr[1])
 >
 >
 > The printed line was "(0, -31) retval = 0 inout1 = -31".
 >

what is Method3 here?  The pippo tests don't have such a method.

But note that in Python, you generally don't see the "hresult" - so it
would be more accurate to have it read something like:

          results = self.object.Method3( in1, inout1)

as Python doesn't have a concept of "byref" args, the "results" object
is a tuple with the return value of the function, if any, plus any
"byref" args created.  In the example above, I'm guessing the function
has returned 0 and one byref arg was presented, with the new value being
-31.

In the VB example below, VB does have byrefs, so the out args end up in
the same argument they were passed in.

I can't explain why VB for -41 for the result when Python got zero
though, but I also can't find the "method3" to help explain it.

Mark


>
> I get "retval = -41 inout1= -31"  if I execute the VBA code:
>
> Sub TestPippo()
>      Dim obj As Pippo
>      Dim in1 As Long
>      Dim inout1 As Long
>
>      Set obj = CreateObject("Python.Test.Pippo")
>      in1 = 1
>      inout1 = 2
>      retval = obj.Method3(in1, inout1)
>      MsgBox ("retval = " & retval & " inout1 = " & inout1)
>
> End Sub
>
>
> Is there a way to call the same Python Server Method, Method3, so that both Python and VBA receive the same return data?
>
> Regards,
> j
> _______________________________________________
> python-win32 mailing list
> [hidden email]
> http://mail.python.org/mailman/listinfo/python-win32
>


_______________________________________________
python-win32 mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/python-win32
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Why does a python COM server return different data to VBA and Python clients?

dived38295
In reply to this post by jeffwelch
Thanks for the reply. I forgot that I had copied Method2 and Method3 from a thread I saw from 2006, 2006-October/005094. That thread just seemed to die without resolution.

I was going to include the differences but I determined why it failed. According to the Microsoft support website "By default, VBA passes arguments by reference."

I would have expected VBA to make an "[in]" parameter use ByVal but that didn't happen, so I did some digging. I found that my example was returning more data than expected. If I removed the extra return value it works and the "[in]" parameter from VBA is not overwritten.
If I forward declare the method in VBA then it detects the extra data and reports an error. I find the VBA behavior a bit confusing.

For anyone interested you can see this behavior using the Pippo test with the following changes:

I added the following line to the "pippo.idl" interface IPippo:
        [id(4), helpstring("method Method3")] HRESULT Method3([in] long in1, [in, out] long *inout1, [out, retval] long *val);
        [id(99), helpstring("method Method4")] HRESULT Method4([in] long in1, [in, out] long *inout1, [out, retval] long *val);

I added the following lines to the pippo_server.py class CPippo. Note that Method 4 is returning an extra value.
    def Method3(self, in1, inout1):
        return( 1010,1011 )
    def Method4(self, in1, inout1):
        return( 1010,1011,1012 )
               
Execute the following VBA code (Excel, or Word have VBA in macros):
        Private Declare Function Pippo_Method3 Lib "TESTSERVERLib.Pippo" (ByVal in1 As Long, inout1 As Long) As Long
        Sub TestPippo()
                  Dim obj As Object
                  Dim in1 As Long
                  Dim inout1 As Long

                  Set obj = CreateObject("Python.Test.Pippo")
                 
                  in1 = -1
                  inout1 = -2
                  retval3 = obj.Method3(in1, inout1)
                  outputMessage = outputMessage & "    Forward declared - Method 3 retval3 = " & retval3 & " inout1 = " & inout1 & " in1 = " & in1 & vbCrLf

                  in1 = -1
                  inout1 = -2
                  retval4 = obj.Method4(in1, inout1)
                  outputMessage = outputMessage & "Not Forward declared - Method 4 retval4 = " & retval4 & " inout1 = " & inout1 & " in1 = " & in1 & vbCrLf

                  MsgBox outputMessage

 End Sub

If you call Method4 from a Python client then it only sees a tuple with 2 elements as expected by the idl. It did seem odd that the VBA saw more data so I guess the Python server method return data is not checked against the registered tlb and just passes the data directly through to the COM client.

J
_______________________________________________
python-win32 mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/python-win32
Loading...