Éric Piel | 20 Jan 15:50
Picon
Picon
Favicon

Right way to call a method with a pointer to array?

Hello,

I'm in a similar situation of what was described previously in this thread:
http://sourceforge.net/mailarchive/message.php?msg_id=25175351

I need to send a pointer to a buffer which will be filled by the method 
as output. The IDL looks like this:
HRESULT GetImage([in] long lSize, [out, size_is(size)] BYTE *pbImage)

With the SVN head of comtypes, it's fairly easy to handle, but I still 
need to do two things:
* Change the generated python class to force pbImage to be 'in' and not 
'out'
* Cast my buffer variable to look like a pointer to a byte, and not an 
array:
   buffer = (c_ubyte * num_bytes)()
   c.GetImage(num_bytes, cast(pointer(buffer), POINTER(c_ubyte)))

So my question: is this the right way to do it?

Would it be possible to modify comptypes to make it easier?
  * Could it be possible to have the tlb parser to detect this case and 
put the parameter as 'in' instead of 'out'?
  * Could it be possible to support the byref() construct like:
   c.GetImage(num_bytes, byref(buffer))
   For now it raises a type exception:
ArgumentError: argument 2: <type 'exceptions.TypeError'>: expected 
LP_c_ubyte instance instead of pointer to c_ubyte_Array_226304

Thanks in advance for your help and input!
(Continue reading)

Thomas Heller | 20 Jan 21:14

Re: Right way to call a method with a pointer to array?

Am 20.01.2012 15:50, schrieb Éric Piel:
> Hello,
>
> I'm in a similar situation of what was described previously in this thread:
> http://sourceforge.net/mailarchive/message.php?msg_id=25175351
>
> I need to send a pointer to a buffer which will be filled by the method
> as output. The IDL looks like this:
> HRESULT GetImage([in] long lSize, [out, size_is(size)] BYTE *pbImage)
>
> With the SVN head of comtypes, it's fairly easy to handle, but I still
> need to do two things:
> * Change the generated python class to force pbImage to be 'in' and not
> 'out'
> * Cast my buffer variable to look like a pointer to a byte, and not an
> array:
>     buffer = (c_ubyte * num_bytes)()
>     c.GetImage(num_bytes, cast(pointer(buffer), POINTER(c_ubyte)))
>
> So my question: is this the right way to do it?

Yes, it seems so.  If it works, I can't test this now.

> Would it be possible to modify comptypes to make it easier?
>    * Could it be possible to have the tlb parser to detect this case and
> put the parameter as 'in' instead of 'out'?

No.  As I said in the thread that you mentioned, the tlb parser cannot 
detect this case since the 'size_is()' info is simply not present in the 
type library (the .tlb file).
(Continue reading)

Éric Piel | 23 Jan 11:18
Picon
Picon
Favicon

Re: Right way to call a method with a pointer to array?

On 20-1-2012 21:14, Thomas Heller wrote:
> Am 20.01.2012 15:50, schrieb Éric Piel:
:
>
>> Would it be possible to modify comptypes to make it easier?
>>     * Could it be possible to have the tlb parser to detect this case and
>> put the parameter as 'in' instead of 'out'?
>
> No.  As I said in the thread that you mentioned, the tlb parser cannot
> detect this case since the 'size_is()' info is simply not present in the
> type library (the .tlb file).
Yes. I looked more into details and I understand better. When a 'out 
pointer' is declared, in VB, you actually pass the variable as 
arguments, even if it's just a int, and you obtain the value by reading 
the variable after the call. But with comtypes, normally comtypes 
allocates the single int itself and you get the value as a return value. 
So in VB, getting an array works the same, while in comtypes it doesn't 
because comtypes just allocates a single element. Maybe one workaround 
would be to have an optional argument to specify the size of the 
allocation (with default of 1)?

>
>>     * Could it be possible to support the byref() construct like:
>>      c.GetImage(num_bytes, byref(buffer))
>>      For now it raises a type exception:
>> ArgumentError: argument 2:<type 'exceptions.TypeError'>: expected
>> LP_c_ubyte instance instead of pointer to c_ubyte_Array_226304
>
> I'm not sure about this.  Does 'c.GetImage(num_bytes, buffer)' work?
Ah! This one probably seemed too easy for me to try ;-) Indeed, it 
(Continue reading)


Gmane