Re: [comtypes-users] Problem calling method [SEC=PERSONAL]

2010-02-22 Thread Pablo Bianucci
Hi Andrew!

On Wed, 17 Feb 2010, Andrew MacIntyre wrote:

 piezo1.GetMaxTravel(APTPiezoLib.CHAN1_ID, pointer(tr))

 I'm curious as to any reasons to prefer the above instead of

 piezo1.GetMaxTravel(APTPiezoLib.CHAN1_ID, byref(tr))

You can chalk it up to my mind working more in C Mode that Visual Basic 
Mode, I guess. :-)
Both seem to work and the first one is the one that popped up initially 
in my mind.

Bye  Good Luck!

Pablo B.


--
Download Intel#174; Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
___
comtypes-users mailing list
comtypes-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/comtypes-users


Re: [comtypes-users] Problem calling method

2010-02-16 Thread Pablo Bianucci
Hi Thomas!

On Mon, 15 Feb 2010, Thomas Heller wrote:

 Here is a patch for comtypes that will pass byref(...) or pointer(...)
 arguments as VT_BYREF variants.  It should workfor Pablos and Michaels
 use cases - also it demonstrates how to access the original object
 of a byref(..) call:

Yup, it works!
Now it is as easy (and intuitive, I'd say) as this:

===
tr = c_float()
piezo1.GetMaxTravel(APTPiezoLib.CHAN1_ID, pointer(tr))
===

Great! Thanks again!

Bye  Good Luck!

Pablo B.

--
SOLARIS 10 is the OS for Data Centers - provides features such as DTrace,
Predictive Self Healing and Award Winning ZFS. Get Solaris 10 NOW
http://p.sf.net/sfu/solaris-dev2dev
___
comtypes-users mailing list
comtypes-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/comtypes-users


Re: [comtypes-users] Problem calling method [SEC=PERSONAL]

2010-02-16 Thread Andrew MacIntyre
 From: Pablo Bianucci
 Now it is as easy (and intuitive, I'd say) as this:
 
 ===
 tr = c_float()
 piezo1.GetMaxTravel(APTPiezoLib.CHAN1_ID, pointer(tr))
 ===

I'm curious as to any reasons to prefer the above instead of

===
tr = c_float()
piezo1.GetMaxTravel(APTPiezoLib.CHAN1_ID, byref(tr))
===

- These thoughts are mine alone! -
Andrew MacIntyre   Operations Branch
tel:   +61 2 6219 5356 Communications Infrastructure Division
fax:   +61 2 6253 3277 Australian Communications  Media Authority
email: andrew.macint...@acma.gov.auhttp://www.acma.gov.au/

If you have received this email in error, please notify the sender immediately 
and erase all copies of the email and any attachments to it. The information 
contained in this email and any attachments may be private, confidential and 
legally privileged or the subject of copyright. If you are not the addressee it 
may be illegal to review, disclose, use, forward, or distribute this email 
and/or its contents.
 
Unless otherwise specified, the information in the email and any attachments is 
intended as a guide only and should not be relied upon as legal or technical 
advice or regarded as a substitute for legal or technical advice in individual 
cases. Opinions contained in this email or any of its attachments do not 
necessarily reflect the opinions of ACMA.

--
SOLARIS 10 is the OS for Data Centers - provides features such as DTrace,
Predictive Self Healing and Award Winning ZFS. Get Solaris 10 NOW
http://p.sf.net/sfu/solaris-dev2dev
___
comtypes-users mailing list
comtypes-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/comtypes-users


Re: [comtypes-users] Problem calling method

2010-02-15 Thread Thomas Heller
Here is a patch for comtypes that will pass byref(...) or pointer(...)
arguments as VT_BYREF variants.  It should workfor Pablos and Michaels
use cases - also it demonstrates how to access the original object
of a byref(..) call:


Index: comtypes/automation.py
===
--- comtypes/automation.py  (revision 564)
+++ comtypes/automation.py  (working copy)
@@ -1,5 +1,6 @@
 # comtypes.automation module
 from ctypes import *
+from ctypes import _Pointer
 from _ctypes import CopyComPointer
 from comtypes import IUnknown, GUID, IID, STDMETHOD, BSTR, COMMETHOD, COMError
 from comtypes.hresult import *
@@ -48,6 +49,7 @@
 # helpers
 IID_NULL = GUID()
 riid_null = byref(IID_NULL)
+_byref_type = type(byref(c_int()))
 
 # 30. December 1899, midnight.  For VT_DATE.
 _com_null_date = datetime.datetime(1899, 12, 30, 0, 0, 0)
@@ -296,6 +298,16 @@
 elif isinstance(value, c_float):
 self.vt = VT_R4
 self._.VT_R4 = value
+elif isinstance(value, _byref_type):
+ref = value._obj
+self._.c_void_p = addressof(ref)
+self.__keepref = value
+self.vt = _ctype_to_vartype[type(ref)] | VT_BYREF
+elif isinstance(value, _Pointer):
+ref = value.contents
+self._.c_void_p = addressof(ref)
+self.__keepref = value
+self.vt = _ctype_to_vartype[type(ref)] | VT_BYREF
 else:
 raise TypeError(Cannot put %r in VARIANT % value)
 # buffer -  SAFEARRAY of VT_UI1 ?

-- 
Thanks,
Thomas


--
SOLARIS 10 is the OS for Data Centers - provides features such as DTrace,
Predictive Self Healing and Award Winning ZFS. Get Solaris 10 NOW
http://p.sf.net/sfu/solaris-dev2dev
___
comtypes-users mailing list
comtypes-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/comtypes-users


Re: [comtypes-users] Problem calling method

2010-02-12 Thread Thomas Heller
Am 11.02.2010 02:32, schrieb Pablo Bianucci:

[...]
From the documentation of this control, I get this prototype (I don't know if
 that's the right name):
 
 ---
 Function GetControlMode(lChanID As Long, plMode As Long) As Long
 
 
 Parameters
 
 lChanID - the channel identifier
 plMode - returns the control loop feedback status
 ---
 
 I found this other funcion, that seems similar and has a code example:
 
 ---
 Function GetMaxTravel(lChanID As Long, plMaxTravel As Long) As Long
 
 
 Parameters
 
 lChanID - the channel identifier
 plMaxTravel - returns the maximum travel (in microns)
 
 Example:
 
 Private Sub cmdGetTravel_Click()
   
   Dim sngMaxTravel As Single
   
   MG17Piezo1.GetMaxTravel CHAN1_ID, sngMaxTravel
   
   ' inform user of piezo max travel
   MsgBox Maximum travel of piezo =   sngMaxTravel
 ---  
 
 Does this help? 

Well, what you could try out are these code snippets in Python:

snip
chanid = 42 # or whatever this needs to be...

print ptr.GetControlMode(chanid) # try to leave out the plMode parameter
print ptr.GetControlMode(chanid, 0) # pass a number for plMode...
print ptr.GetMaxTravle(chanid)
print ptr.GetMaxTravel(chanid, 0)
/snip

If nonthing of the above works, I guess you would have to pass the second 
parameter
by reference.  The basic code would have to look something like this; it
is basically what I assume that VB does:

snip
# create a variable containing the 'control loop feedback status',
# initialized to some value
mode = c_int(0)

# Call the function, passing the VALUE of chanid,
# and a REFERENCE to the 'mode' variable.
print ptr.GetControlMode(chanid, pass_by_reference(mode))
# The result of the function call should now have been printed,
# and the 'mode' variable should contain an updated value:

print mode.value
/snip

Ok, but what is this pass_by_reference() function?

It should take the argument (a ctypes c_int instance, for example),
and convert to something that will eventually, in the Invoke call,
used as BYREF VARIANT argument.

I'll try to come up with some ideas for that if the first code snippet
above really fails.

 
 However, it could be that comtypes is not able to call this method...
 
 I hope not! (crossing fingers... :-))

We'll see.

-- 
Thanks,
Thomas


--
SOLARIS 10 is the OS for Data Centers - provides features such as DTrace,
Predictive Self Healing and Award Winning ZFS. Get Solaris 10 NOW
http://p.sf.net/sfu/solaris-dev2dev
___
comtypes-users mailing list
comtypes-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/comtypes-users


Re: [comtypes-users] Problem calling method

2010-02-12 Thread Thomas Heller
Am 12.02.2010 20:24, schrieb Pablo Bianucci:
 Hi Thomas!
 
 On Fri, 12 Feb 2010, Pablo Bianucci wrote:
 
 Exception: Cannot put cparam 'P' (012D7468) in VARIANT
 
 The problem seems to be that the initialization of VARIANT does not know 
 what to do with a pointer type. I think that VARIANT could be extended to 
 handle those:
 
 Get the value of the pointer (no the contents but the actual address), 
 store that as the content of the VARIANT instance and then set the 
 VT_BYREF flag. Do you think that would work?

Exactly.  I cannot provide a patch, but here's a code snippet that creates
such a beast:

from comtypes.automation import *

mode = c_int(42) # our variable
v = VARIANT()
v._.c_void_p = cast(pointer(mode), c_void_p)
v.vt = VT_BYREF | VT_I4

print v # prints 'VARIANT(vt=0x4003, byref(42))'

You could use this stuff and pass it to Invoke.  I assume that is
will be changed after the call.  Pretty straightforward to retrieve
the result; VARIANT contains code for that.
Since the VARIANT is a kind of pointer, I have chosen the indexing
to acces the contained value:

print v # prints 'VARIANT(vt=0x4003, byref(42))'
print v[0] # prints '42'

 What I don't see how to do is how to get the address pointed to as a plain 
 number.

cast does that for you, without worring about the actual address.

-- 
Thanks,
Thomas

--
SOLARIS 10 is the OS for Data Centers - provides features such as DTrace,
Predictive Self Healing and Award Winning ZFS. Get Solaris 10 NOW
http://p.sf.net/sfu/solaris-dev2dev
___
comtypes-users mailing list
comtypes-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/comtypes-users


Re: [comtypes-users] Problem calling method

2010-02-12 Thread Pablo Bianucci
Hi Thomas!

On Fri, 12 Feb 2010, Thomas Heller wrote:

 Exactly.  I cannot provide a patch, but here's a code snippet that creates
 such a beast:

Yes! It works!!

This is the final working snippet:

snip
travel = c_float(0)
v = VARIANT()
v._.c_void_p = cast(pointer(travel), c_void_p)
v.vt = VT_BYREF | VT_R4

mode = c_int(0)
vm = VARIANT()
vm._.c_void_p = cast(pointer(mode), c_void_p)
vm.vt = VT_BYREF | VT_I4

try:
 piezo1.GetMaxTravel(APTPiezoLib.CHAN1_ID, v)
 piezo1.GetControlMode(APTPiezoLib.CHAN1_ID,  vm)
except Exception, e:
 print Exception:, e
print travel.value, mode.value
/snip

If you are not careful when setting the types you get a Type Mismatch 
error (even though the protoypes in the help were the same, I had to use 
different types for the two funcions there).

I wonder why you can't integrate this into the package. I'm fine as this, 
as this will let me write the program I need, but it would be more user 
friendly to be able use pointers as arguments for the method invocation. 
But I don't understand COM internals, so it could be that implementing 
that could lead to other problems.

Thank you very much for your help!

Bye  Good Luck!

Pablo.

P.S.: If you visit Canada and stay at a city I happen to be living in, 
consider yourself invited to a drink. ;-)


--
SOLARIS 10 is the OS for Data Centers - provides features such as DTrace,
Predictive Self Healing and Award Winning ZFS. Get Solaris 10 NOW
http://p.sf.net/sfu/solaris-dev2dev
___
comtypes-users mailing list
comtypes-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/comtypes-users


Re: [comtypes-users] Problem calling method

2010-02-12 Thread Michael Curran
Hi,

Recently we noticed the same problem with our project.

We access the MS Word object model via IDispatch, but  there is a 
GetPoint method which takes left, top, hight and width as byref arguments.

As comtypes doesn't support vt_byref out of the box, our first idea was 
to rewrite the code for VARIANT._set_value(), and provide comtypes with 
a patch.

However, looking at VARIANT._set_value():
  There are lots of returns all the way through the function, so its 
clear it would have to be rewritten almost from the ground up. And since 
I'm not too skilled with all of the VARIANT types, I don't want to break 
any existing logic.

So, what we currently do, is when our project imports comtypes at 
initialization time, we do the following:

#Monkey patch comtypes to support byref in variants
from comtypes.automation import VARIANT, VT_BYREF
from ctypes import cast, c_void_p
from _ctypes import _Pointer

oldVARIANT_value_fset=VARIANT.value.fset

def newVARIANT_value_fset(self,value):
realValue=value
if isinstance(value,_Pointer):
try:
value=value.contents
except (NameError,AttributeError):
pass
oldVARIANT_value_fset(self,value)
if realValue is not value:
self.vt|=VT_BYREF
self._.c_void_p=cast(realValue,c_void_p)

VARIANT.value=property(VARIANT.value.fget,newVARIANT_value_fset,VARIANT.value.fdel)

So, from then on, when ever passing an instance of a POINTER of a ctypes 
type, comtypes will automatically treet the value as byref.

Some example code for GetPoint:

from ctypes import c_long, pointer
rangeLeft=c_long()
rangeTop=c_long()
rangeWidth=c_long()
rangeHeight=c_long()
 
self.obj.WinwordWindowObject.getPoint(pointer(rangeLeft),pointer(rangeTop),pointer(rangeWidth),pointer(rangeHeight),self._rangeObj)

I would probably prefer that we use ctypes.byref, rather than 
ctypes.POINTER, as the name relates better to what its doing. But, 
ctypes.byref(x) yields an object who's type is something like 
type(cArgObject), which I can't find anywhere in ctypes or _ctypes. So, 
it would be a little hard for VARIANT._set_value to properly identify 
that value was a byref.

Interestingly enough though,  if comtypes compiles the actual COM 
interfaces for the MS Word object model, POINTER is used anyway, so I 
guess POINTER is ok.

Mick




On 13/02/2010 10:48 AM, Pablo Bianucci wrote:
 Hi Thomas!

 On Fri, 12 Feb 2010, Thomas Heller wrote:

 Exactly.  I cannot provide a patch, but here's a code snippet that creates
 such a beast:

 Yes! It works!!

 This is the final working snippet:

 snip
 travel = c_float(0)
 v = VARIANT()
 v._.c_void_p = cast(pointer(travel), c_void_p)
 v.vt = VT_BYREF | VT_R4

 mode = c_int(0)
 vm = VARIANT()
 vm._.c_void_p = cast(pointer(mode), c_void_p)
 vm.vt = VT_BYREF | VT_I4

 try:
   piezo1.GetMaxTravel(APTPiezoLib.CHAN1_ID, v)
   piezo1.GetControlMode(APTPiezoLib.CHAN1_ID,  vm)
 except Exception, e:
   print Exception:, e
 print travel.value, mode.value
 /snip

 If you are not careful when setting the types you get a Type Mismatch
 error (even though the protoypes in the help were the same, I had to use
 different types for the two funcions there).

 I wonder why you can't integrate this into the package. I'm fine as this,
 as this will let me write the program I need, but it would be more user
 friendly to be able use pointers as arguments for the method invocation.
 But I don't understand COM internals, so it could be that implementing
 that could lead to other problems.

 Thank you very much for your help!

 Bye  Good Luck!

 Pablo.

 P.S.: If you visit Canada and stay at a city I happen to be living in,
 consider yourself invited to a drink. ;-)


 --
 SOLARIS 10 is the OS for Data Centers - provides features such as DTrace,
 Predictive Self Healing and Award Winning ZFS. Get Solaris 10 NOW
 http://p.sf.net/sfu/solaris-dev2dev
 ___
 comtypes-users mailing list
 comtypes-users@lists.sourceforge.net
 https://lists.sourceforge.net/lists/listinfo/comtypes-users


-- 
Michael Curran
President, NV Access Inc
Email: m...@nvaccess.org
Website: www.nvaccess.org
ABN 61773362390.

--
SOLARIS 10 is the OS for Data Centers - provides features such as DTrace,
Predictive Self Healing and Award Winning ZFS. Get Solaris 10 NOW
http://p.sf.net/sfu/solaris-dev2dev
___
comtypes-users mailing list
comtypes-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/comtypes-users


Re: [comtypes-users] Problem calling method

2010-02-10 Thread Thomas Heller
Am 30.01.2010 06:23, schrieb Pablo Bianucci:
 Hi!
 
 I am trying to use an ActiveX control (.OCX, from a piezo electric stage
 controller)) from a Python program. I have managed to get the control to work,
 but I am having problems calling a method.
 
 This is the method in question (from the autogenerated typelib):
 
 ===
DISPMETHOD([dispid(20)], c_int, 'GetControlMode',
( [], c_int, 'lChanID' ),
( [], POINTER(c_int), 'plMode' )),
 ===
 
 This is what I am doing trying to use the method (it should give me an 
 integer):
 
 ===
 mode = 0
 mode_ptr = cast(mode, POINTER(c_int))

What you are doing here is that you create a NULL pointer - which is probably 
not
what you want.  But see below.

 try:
 piezo1.GetControlMode(APTPiezoLib.CHAN1_ID, mode_ptr)
 except Exception, e:
 print Exception:, e
 ===
 
 And I get:
 
 ===
 Exception: Cannot put comtypes._safearray.LP_c_long object at 0x012D9440 in 
 VARIANT
 ===i
 
 I have no previous experience with comtypes or ctypes (or Win32 programming, 
 for that matter ;-)), so I might be doing something stupidly wrong. I've tried
 all the permutations I could think of already, so I need expert help. 

Ok, the interface that you have is a pure dispinterface, which means that
all methods of the COM object are eventually called as IDispatch.Invoke() calls.

The Invoke() method packs all parameters into a DISPPARAM structure which
basically is an array of VARIANT instances.  This explains the error that
you get - comtypes is trying to pack the POINTER parameter that you have
created into a VARIANT.  This only works for 'automation-compatible' data types
and your pointer is not one of those.

I would guess that the 'mode_ptr' argument is an argument that must be passed
by reference (this is visual basic speak).  Do you have sample VB code that
shows how this method is used?

However, it could be that comtypes is not able to call this method...

Thomas


--
SOLARIS 10 is the OS for Data Centers - provides features such as DTrace,
Predictive Self Healing and Award Winning ZFS. Get Solaris 10 NOW
http://p.sf.net/sfu/solaris-dev2dev
___
comtypes-users mailing list
comtypes-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/comtypes-users