Re: How to write partial of a buffer which was returned from a C function to a file?

2018-04-14 Thread Jach Fong

Gregory Ewing at 2018/4/15 PM 08:20 wrote:

Jach Fong wrote:

 >>> pvoid = ctypes.c_void_p(ctypes.addressof(buf0))
 >>> pvoid.contents
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: 'c_void_p' object has no attribute 'contents'


I think the 'contents' attribute only applies to pointers that are
pointing at part of another Python object. Your c_void_p instance
is not that kind of pointer.

I must say the ctypes documentation is rather confusing when it
comes to these kinds of details. It doesn't help that the "Pointers
and Arrays" section is marked as "Not yet written". Does anyone
have any plans to finish it?


>>> pt = ctypes.cast(buf0, ctypes.POINTER(ctypes.c_void_p))
>>> type(pt)

>>> pt.contents
c_void_p(1835102323)

From the API point of view, I think it's better not to dive into the 
ocean of "type" too deeply, especially when foreign language was 
involved. You may get totally confused. (unless you want to write code 
like in the IOCCC contest:-)


I have to admit that the ctypes' document was written pretty well. Most 
of my problems were caused by that I didn't read it thoughtfully:-(


--Jach

---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus

--
https://mail.python.org/mailman/listinfo/python-list


Re: How to write partial of a buffer which was returned from a C function to a file?

2018-04-14 Thread Gregory Ewing

Jach Fong wrote:

 >>> pvoid = ctypes.c_void_p(ctypes.addressof(buf0))
 >>> pvoid.contents
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: 'c_void_p' object has no attribute 'contents'


I think the 'contents' attribute only applies to pointers that are
pointing at part of another Python object. Your c_void_p instance
is not that kind of pointer.

I must say the ctypes documentation is rather confusing when it
comes to these kinds of details. It doesn't help that the "Pointers
and Arrays" section is marked as "Not yet written". Does anyone
have any plans to finish it?

--
Greg
--
https://mail.python.org/mailman/listinfo/python-list


Re: How to write partial of a buffer which was returned from a C function to a file?

2018-04-13 Thread eryk sun
On Sat, Apr 14, 2018 at 1:57 AM, Jach Fong  wrote:
> eryk sun at 2018/4/14 PM 05:27 wrote:
>
>> The simple types c_void_p, c_char_p, and c_wchar_p are pointers.
>> However, since they subclass _SimpleCData instead of _Pointer, they
>> inherit the behavior of simple types.
>
> The ctypes document says:
> "Pointer instances have a contents attribute which returns the object to
> which the pointer points"
>
 buf0 = ctypes.create_string_buffer(b'spam')
>
 pvoid = ctypes.c_void_p(ctypes.addressof(buf0))
 pvoid.contents
> Traceback (most recent call last):
>   File "", line 1, in 
> AttributeError: 'c_void_p' object has no attribute 'contents'
 pvoid.value
> 35425816
>
 pp = ctypes.pointer(buf0)
 pp.contents
> 
 pp.value
> Traceback (most recent call last):
>   File "", line 1, in 
> AttributeError: 'LP_c_char_Array_5' object has no attribute 'value'
>
> It looks like the c_void_p is not of a pointer type:-)

c_void_p is a `void *` pointer type, but it's a simple pointer type
that subclasses _SimpleCData instead of _Pointer, so it doesn't have a
`contents` property but instead has a `value` property.

>>> hasattr(ctypes._SimpleCData, 'contents')
False
>>> hasattr(ctypes._SimpleCData, 'value')
True
>>> hasattr(ctypes._Pointer, 'contents')
True
>>> hasattr(ctypes._Pointer, 'value')
False

Don't take the Python class hierarchy so literally that you overlook
what these types ultimately are in C. Just because they don't subclass
_Pointer, that doesn't mean they're not pointer types. c_void_p,
c_char_p, and c_wchar_p are unquestionably pointer types. This is what
the "_p" suffix means in their names. It's just these particular
pointer types were implemented as simple types to get the convenience
of implicit conversion. That said, sometimes the implicit conversion
is a problem, in which case we use, for example, POINTER(c_char)
instead of c_char_p.

Look in Lib/ctypes/__init__.py to review the definitions for yourself.
Here they are without the __repr__ methods:

class c_void_p(_SimpleCData):
_type_ = "P"

class c_char_p(_SimpleCData):
_type_ = "z"

class c_wchar_p(_SimpleCData):
_type_ = "Z"

This doesn't tell you much. You have to go looking for what it means
to be a simple "P" type, and in particular we're concerned with how
conversion to and from native Python types is implemented. You'll find
the get and set C implementations for types "P", "z", and "Z" defined
in Modules/_ctypes/cfield.c.

For example, for type "P", it's P_get() and P_set(). For P_get(), we
use PyLong_FromVoidPtr to convert the pointer value to a Python
integer, except we return None for a NULL pointer. For P_set(), we
require an integer value or None (NULL). Note that the function to
convert a Python integer to an integral address in C depends on the
size of a C `long` or `long long` compared to the size of a C `void *`
pointer. In particular, this design accommodates 64-bit Windows, on
which a `long` is 32-bit and thus too small for a 64-bit pointer
value, so we call PyLong_AsUnsignedLongLongMask instead of
PyLong_AsUnsignedLongMask.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How to write partial of a buffer which was returned from a C function to a file?

2018-04-13 Thread Jach Fong

eryk sun at 2018/4/14 PM 05:27 wrote:

On Fri, Apr 13, 2018 at 8:44 AM, Jach Fong  wrote:


After studying the example you explained in your previous post replied to
Gregory Ewing, I had noticed that until today I was totally misunderstand
the meaning of the c_char_p. I always think it "is" a pointer, but actually
it's just a ctypes type, maybe literarily looks like a C pointer, but not a
pointer from the ctypes view at all:-)


Here's a list of type classes in ctypes:

 class metaclass
 =
 _SimpleCData  PyCSimpleType
 _Pointer  PyCPointerType
 _CFuncPtr PyCFuncPtrType
 Array PyCArrayType
 Structure PyCStructType
 Union UnionType

These classes share a common _CData base class. Note that the _ctypes
extension module doesn't directly expose _CData, nor any of the
metaclasses.

ctypes type checking primarily uses Python type checking, so we
generally do not subclass these types directly, except for Structure
and Union. Instead we have a set of predefined simple types that
subclass _SimpleCData (e.g. c_int, c_char), and we use factory
functions to create pointer types (e.g. POINTER, CFUNCTYPE), which
cache the created type. For arrays, we rely on the base _CData
sequence-repeat functionality (e.g. c_int * 3), which also caches the
Array subclass that it creates.

Type caching ensures that two expressions that create an equivalent C
type return the same class. For example, if you have `c_char * 3` in
two places, it should be the same type:

 >>> cls = ctypes.c_char * 3
 >>> (ctypes.c_char * 3) is cls
 True
Thanks for your description. To digest it, I may need to dive into its 
source jungle:-(



The simple types c_void_p, c_char_p, and c_wchar_p are pointers.
However, since they subclass _SimpleCData instead of _Pointer, they
inherit the behavior of simple types.


The ctypes document says:
"Pointer instances have a contents attribute which returns the object to 
which the pointer points"


>>> buf0 = ctypes.create_string_buffer(b'spam')

>>> pvoid = ctypes.c_void_p(ctypes.addressof(buf0))
>>> pvoid.contents
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: 'c_void_p' object has no attribute 'contents'
>>> pvoid.value
35425816

>>> pp = ctypes.pointer(buf0)
>>> pp.contents

>>> pp.value
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: 'LP_c_char_Array_5' object has no attribute 'value'

It looks like the c_void_p is not of a pointer type:-)

--Jach


In particular they have get/set
functions that implicitly convert to and from native Python types when
they're used in aggregate types (arrays, structs, unions), when
indexing or slicing a _Pointer instance, or as the result or argument
of a function pointer (i.e. _CFuncPtr subclass).



---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus

--
https://mail.python.org/mailman/listinfo/python-list


Re: How to write partial of a buffer which was returned from a C function to a file?

2018-04-13 Thread eryk sun
On Fri, Apr 13, 2018 at 8:44 AM, Jach Fong  wrote:
>
> After studying the example you explained in your previous post replied to
> Gregory Ewing, I had noticed that until today I was totally misunderstand
> the meaning of the c_char_p. I always think it "is" a pointer, but actually
> it's just a ctypes type, maybe literarily looks like a C pointer, but not a
> pointer from the ctypes view at all:-)

Here's a list of type classes in ctypes:

class metaclass
=
_SimpleCData  PyCSimpleType
_Pointer  PyCPointerType
_CFuncPtr PyCFuncPtrType
Array PyCArrayType
Structure PyCStructType
Union UnionType

These classes share a common _CData base class. Note that the _ctypes
extension module doesn't directly expose _CData, nor any of the
metaclasses.

ctypes type checking primarily uses Python type checking, so we
generally do not subclass these types directly, except for Structure
and Union. Instead we have a set of predefined simple types that
subclass _SimpleCData (e.g. c_int, c_char), and we use factory
functions to create pointer types (e.g. POINTER, CFUNCTYPE), which
cache the created type. For arrays, we rely on the base _CData
sequence-repeat functionality (e.g. c_int * 3), which also caches the
Array subclass that it creates.

Type caching ensures that two expressions that create an equivalent C
type return the same class. For example, if you have `c_char * 3` in
two places, it should be the same type:

>>> cls = ctypes.c_char * 3
>>> (ctypes.c_char * 3) is cls
True

The simple types c_void_p, c_char_p, and c_wchar_p are pointers.
However, since they subclass _SimpleCData instead of _Pointer, they
inherit the behavior of simple types. In particular they have get/set
functions that implicitly convert to and from native Python types when
they're used in aggregate types (arrays, structs, unions), when
indexing or slicing a _Pointer instance, or as the result or argument
of a function pointer (i.e. _CFuncPtr subclass).
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How to write partial of a buffer which was returned from a C function to a file?

2018-04-13 Thread Jach Fong

eryk sun at 2018/4/13 PM 12:16 wrote:

On Fri, Apr 13, 2018 at 12:38 AM, Jach Fong  wrote:

Gregory Ewing at 2018/4/13 上午 07:25 wrote:


To get around this, you may need to declare the return type
as POINTER(c_char) instead:


For a general character pointer that may also point to binary data,


  > POINTER(c_char) must be used.


I had missed this statement:-(

To make a quick try, I set the function's restype to
ctypes.POINTER(ctypes.c_ubyte), instead of ctypes.c_char_p. It's amazing,
the \x00 trap can be avoided in this way. Now I can use "mydata =
bytes(buf[:n])" to extract n bytes of data and write it to file.


Slicing a ctypes.POINTER(ctypes.c_char) pointer returns bytes without
having to make a third copy via the bytes constructor. (Note that
c_char is the fundamental C char integer type, not to be confused with
c_char_p, which is a char * pointer.) However, if you're working with
multi-megabyte data buffers,it's more efficient and safer to use an
array view (ctypes or NumPy) on the returned buffer.


After studying the example you explained in your previous post replied 
to Gregory Ewing, I had noticed that until today I was totally 
misunderstand the meaning of the c_char_p. I always think it "is" a 
pointer, but actually it's just a ctypes type, maybe literarily looks 
like a C pointer, but not a pointer from the ctypes view at all:-)


from the ctypes document:
"Pointer instances are created by calling the pointer() function on a 
ctypes type"


"Fundamental data types, when returned as foreign function call results, 
or, for example, by retrieving structure field members or array items, 
are transparently converted to native Python types. In other words, if a 
foreign function has a restype of c_char_p, you will always receive a 
Python bytes object, not a c_char_p instance"


That's the reason I was failed at first using c_char_p as a pointer to 
the returned C buffer. There is no fundamental pointer type in ctypes. 
If a pointer was needed, you have to create it manually. That's why the 
second try works.


Anyway, thanks for help on cleaning my head:-)

--Jach



In most cases, you should free the returned pointer after you're
finished processing the data buffer, else you'll have a memory leak.
The library should export a function for this.



---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus

--
https://mail.python.org/mailman/listinfo/python-list


Re: How to write partial of a buffer which was returned from a C function to a file?

2018-04-12 Thread eryk sun
On Fri, Apr 13, 2018 at 12:38 AM, Jach Fong  wrote:
> Gregory Ewing at 2018/4/13 上午 07:25 wrote:
>
>> To get around this, you may need to declare the return type
>> as POINTER(c_char) instead:
>>
>>> For a general character pointer that may also point to binary data,
>>
>>  > POINTER(c_char) must be used.
>
> I had missed this statement:-(
>
> To make a quick try, I set the function's restype to
> ctypes.POINTER(ctypes.c_ubyte), instead of ctypes.c_char_p. It's amazing,
> the \x00 trap can be avoided in this way. Now I can use "mydata =
> bytes(buf[:n])" to extract n bytes of data and write it to file.

Slicing a ctypes.POINTER(ctypes.c_char) pointer returns bytes without
having to make a third copy via the bytes constructor. (Note that
c_char is the fundamental C char integer type, not to be confused with
c_char_p, which is a char * pointer.) However, if you're working with
multi-megabyte data buffers,it's more efficient and safer to use an
array view (ctypes or NumPy) on the returned buffer.

In most cases, you should free the returned pointer after you're
finished processing the data buffer, else you'll have a memory leak.
The library should export a function for this.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How to write partial of a buffer which was returned from a C function to a file?

2018-04-12 Thread Jach Fong


Gregory Ewing at 2018/4/13 上午 07:25 wrote:

On Thu, Apr 12, 2018 at 2:16 PM,   wrote:


This C function returns a buffer which I declared it as a
ctypes.c_char_p. The buffer has size 0x1 bytes long and the valid
data may vary from a few bytes to the whole size.


I think we need to see the code you're using to call this
C function.

The crucial issue is: are *you* allocating this 0x1 byte
buffer and telling the function to read data into it, or
does the function allocate the memory itself and return a
pointer to it?


I am working on a DLL's function.



If the function is allocating the buffer, then I don't
think there's any way to make this work. The ctypes docs
say this:

Fundamental data types, when returned as foreign function call results 
... are
transparently converted to native Python types. In other words, if a 
foreign
function has a restype of c_char_p, you will always receive a Python 
bytes

object, not a c_char_p instance.


The problem is that the only way ctypes can tell how long
a bytes object to create for a c_char_p is by assuming that
it points to a nul-terminated string. If it actually points
to a char array that can legitimately contain zero bytes,
then you're out of luck.

To get around this, you may need to declare the return type
as POINTER(c_char) instead:


For a general character pointer that may also point to binary data,

 > POINTER(c_char) must be used.


I had missed this statement:-(

To make a quick try, I set the function's restype to 
ctypes.POINTER(ctypes.c_ubyte), instead of ctypes.c_char_p. It's 
amazing, the \x00 trap can be avoided in this way. Now I can use "mydata 
= bytes(buf[:n])" to extract n bytes of data and write it to file.


The problem was solved, and thanks for all your help.

--Jach


I'm not sure where to go from here, though, because the
ctypes documentation peters out before explaining exactly
what can be done with a POINTER object.

Another approach would be to allocate the buffer yourself
and pass it into the C function, but whether that's possible
depends on the details of the C API you're using.



---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus

--
https://mail.python.org/mailman/listinfo/python-list


Re: How to write partial of a buffer which was returned from a C function to a file?

2018-04-12 Thread eryk sun
On Thu, Apr 12, 2018 at 11:25 PM, Gregory Ewing
 wrote:
>
> To get around this, you may need to declare the return type
> as POINTER(c_char) instead:
>
>> For a general character pointer that may also point to binary data,
>
>> POINTER(c_char) must be used.
>
> I'm not sure where to go from here, though, because the
> ctypes documentation peters out before explaining exactly
> what can be done with a POINTER object.

Pointers can be indexed and sliced. You have to be careful, however,
since there's no bounds checking. Alternatively, without copying, you
can create an array view on the buffer, which is bounded and thus
doesn't risk an access violation (segfault). For example:

Say the function returns a pointer to a buffer with the contents
b"spam\x00". Let's simulate the function result using a void * pointer
to initialize a char * pointer:

>>> buf0 = ctypes.create_string_buffer(b'spam')
>>> pvoid = ctypes.c_void_p(ctypes.addressof(buf0))
>>> result = ctypes.POINTER(ctypes.c_char).from_buffer_copy(pvoid)

This pointer object has just the address of the buffer, without
supporting references in _b_base_ or _objects:

>>> result._b_base_ is result._objects is None
True

(In other words, ctypes isn't responsible for the buffer, as simulated
here. Libraries that allocate their own memory for results have to
provide a function to free it. Especially on Windows, you cannot rely
on both Python and the DLL to use the same heap.)

You can slice the pointer:

>>> result[:5]
b'spam\x00'

Or you can access the buffer more safely as a new array view:

>>> array_t = ctypes.c_char * 5
>>> pointer_t = ctypes.POINTER(array_t)
>>> result.contents
c_char(b's')

>>> buf1 = pointer_t(result.contents)[0]
>>> buf1[:]
b'spam\x00'

This buf1 array is a view on the buffer, not a copy. It reflects
whatever changes are made to the underlying buffer:

>>> buf0[:] = b'eggs\x00'
>>> buf1[:]
b'eggs\x00'

As such, ctypes knows it doesn't have to free this memory:

>>> buf1._b_needsfree_
0
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How to write partial of a buffer which was returned from a C function to a file?

2018-04-12 Thread Cameron Simpson

On 12Apr2018 16:11, Jach Fong  wrote:
This is the first time I am using python-list to interact with 
comp.lang.python forum (because there are so many spam when using 
browser to view it) so forgive me if something goes wrong.


Python already treat the returned buffer as 'bytes'. The problem is 
Python don't know its size (or decides it wrong:-).


I think you'll need to show us your code. It isn't clear to me your problem is.

Cheers,
Cameron Simpson 
--
https://mail.python.org/mailman/listinfo/python-list


Re: How to write partial of a buffer which was returned from a C function to a file?

2018-04-12 Thread Gregory Ewing

On Thu, Apr 12, 2018 at 2:16 PM,   wrote:


This C function returns a buffer which I declared it as a
ctypes.c_char_p. The buffer has size 0x1 bytes long and the valid
data may vary from a few bytes to the whole size.


I think we need to see the code you're using to call this
C function.

The crucial issue is: are *you* allocating this 0x1 byte
buffer and telling the function to read data into it, or
does the function allocate the memory itself and return a
pointer to it?

If the function is allocating the buffer, then I don't
think there's any way to make this work. The ctypes docs
say this:


Fundamental data types, when returned as foreign function call results ... are
transparently converted to native Python types. In other words, if a foreign
function has a restype of c_char_p, you will always receive a Python bytes
object, not a c_char_p instance.


The problem is that the only way ctypes can tell how long
a bytes object to create for a c_char_p is by assuming that
it points to a nul-terminated string. If it actually points
to a char array that can legitimately contain zero bytes,
then you're out of luck.

To get around this, you may need to declare the return type
as POINTER(c_char) instead:


For a general character pointer that may also point to binary data,

> POINTER(c_char) must be used.

I'm not sure where to go from here, though, because the
ctypes documentation peters out before explaining exactly
what can be done with a POINTER object.

Another approach would be to allocate the buffer yourself
and pass it into the C function, but whether that's possible
depends on the details of the C API you're using.

--
Greg
--
https://mail.python.org/mailman/listinfo/python-list


Re: How to write partial of a buffer which was returned from a C function to a file?

2018-04-12 Thread Albert-Jan Roskam

On Apr 12, 2018 09:39, jf...@ms4.hinet.net wrote:
>
> Chris Angelico於 2018年4月12日星期四 UTC+8下午1時31分35秒寫道:
> > On Thu, Apr 12, 2018 at 2:16 PM,   wrote:
> > > This C function returns a buffer which I declared it as a 
> > > ctypes.c_char_p. The buffer has size 0x1 bytes long and the valid 
> > > data may vary from a few bytes to the whole size.
> > >
> > > In every call I know how much the valid data size is, but I suppose I 
> > > can't use slice to get it because there may be zero byte in it. What to 
> > > do?
> > >
> >
> > You suppose? Or have you tested it?
> >
> > ChrisA
>
> Yes, I had test it once before. Now, I re-do it again to make sure. After a 
> call which returns 3 bytes of data, I use len(buf) to check the length and 
> get the number 24. I can see the first 24 bytes of data by using buf[:30] but 
> buf[24] will cause an "index out of range" error. I don't know how to see 
> what the buf[24] exactly is but I suppose it might be a zero byte.

Aren't you looking for the .value or the .raw property?
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How to write partial of a buffer which was returned from a C function to a file?

2018-04-12 Thread Jach Fong
This is the first time I am using python-list to interact with 
comp.lang.python forum (because there are so many spam when using 
browser to view it) so forgive me if something goes wrong.


Python already treat the returned buffer as 'bytes'. The problem is 
Python don't know its size (or decides it wrong:-).


--Jach

Cameron Simpson at 2018/4/12 PM 02:28 wrote:

On 11Apr2018 21:16, jf...@ms4.hinet.net  wrote:
This C function returns a buffer which I declared it as a 
ctypes.c_char_p. The buffer has size 0x1 bytes long and the valid 
data may vary from a few bytes to the whole size.


Could you show us the function?

In every call I know how much the valid data size is, but I suppose I 
can't use slice to get it because there may be zero byte in it. What 
to do?


Why not just return bytes? Allocate one of the correct size and copy the 
bytes into it, then return?


Of course it is all hard to say without seeing some actual code.

Cheers,
Cameron Simpson 





---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus

--
https://mail.python.org/mailman/listinfo/python-list


Re: How to write partial of a buffer which was returned from a C function to a file?

2018-04-12 Thread jfong
Chris Angelico於 2018年4月12日星期四 UTC+8下午4時05分29秒寫道:
> On Thu, Apr 12, 2018 at 4:20 PM,   wrote:
> > Chris Angelico於 2018年4月12日星期四 UTC+8下午1時31分35秒寫道:
> >> On Thu, Apr 12, 2018 at 2:16 PM,   wrote:
> >> > This C function returns a buffer which I declared it as a 
> >> > ctypes.c_char_p. The buffer has size 0x1 bytes long and the valid 
> >> > data may vary from a few bytes to the whole size.
> >> >
> >> > In every call I know how much the valid data size is, but I suppose I 
> >> > can't use slice to get it because there may be zero byte in it. What to 
> >> > do?
> >> >
> >>
> >> You suppose? Or have you tested it?
> >>
> >> ChrisA
> >
> > Yes, I had test it once before. Now, I re-do it again to make sure. After a 
> > call which returns 3 bytes of data, I use len(buf) to check the length and 
> > get the number 24. I can see the first 24 bytes of data by using buf[:30] 
> > but buf[24] will cause an "index out of range" error. I don't know how to 
> > see what the buf[24] exactly is but I suppose it might be a zero byte.
> >
> 
> If you have 24 bytes, they're numbered 0 through 23. So there is no byte at 
> 24.
> 
> ChrisA

Using a technique you mentioned in subject "how to memory dump an object?" at 
16/5/21, I confirm the length of buf was decided by a \x00 byte:

>>> len(buf)
24
>>> id(buf)
13553888
>>> ptr = ctypes.cast(id(buf), ctypes.POINTER(ctypes.c_ubyte))
>>> buf[:24]
b'\x05ALLOTNPUT_BUFFER_SIZE\x02+'
>>> bytes([ptr[i] for i in range(50)])
b'\x02\x00\x00\x00X\xa1%\x1e\x18\x00\x00\x00\xff\xff\xff\xff\x05ALLOTNPUT_BUFFER_SIZE\x02+\x00\n\x00\x00\x00\x00\x00\x00\xb0\x9b'
>>>

but it won't help on solving my problem. Still need someone's help:-)

--Jach
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How to write partial of a buffer which was returned from a C function to a file?

2018-04-12 Thread Cameron Simpson

On 11Apr2018 21:16, jf...@ms4.hinet.net  wrote:

This C function returns a buffer which I declared it as a ctypes.c_char_p. The 
buffer has size 0x1 bytes long and the valid data may vary from a few bytes 
to the whole size.


Could you show us the function?

In every call I know how much the valid data size is, but I suppose I can't 
use slice to get it because there may be zero byte in it. What to do?


Why not just return bytes? Allocate one of the correct size and copy the bytes 
into it, then return?


Of course it is all hard to say without seeing some actual code.

Cheers,
Cameron Simpson 
--
https://mail.python.org/mailman/listinfo/python-list


Re: How to write partial of a buffer which was returned from a C function to a file?

2018-04-12 Thread Chris Angelico
On Thu, Apr 12, 2018 at 4:20 PM,   wrote:
> Chris Angelico於 2018年4月12日星期四 UTC+8下午1時31分35秒寫道:
>> On Thu, Apr 12, 2018 at 2:16 PM,   wrote:
>> > This C function returns a buffer which I declared it as a ctypes.c_char_p. 
>> > The buffer has size 0x1 bytes long and the valid data may vary from a 
>> > few bytes to the whole size.
>> >
>> > In every call I know how much the valid data size is, but I suppose I 
>> > can't use slice to get it because there may be zero byte in it. What to do?
>> >
>>
>> You suppose? Or have you tested it?
>>
>> ChrisA
>
> Yes, I had test it once before. Now, I re-do it again to make sure. After a 
> call which returns 3 bytes of data, I use len(buf) to check the length and 
> get the number 24. I can see the first 24 bytes of data by using buf[:30] but 
> buf[24] will cause an "index out of range" error. I don't know how to see 
> what the buf[24] exactly is but I suppose it might be a zero byte.
>

If you have 24 bytes, they're numbered 0 through 23. So there is no byte at 24.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How to write partial of a buffer which was returned from a C function to a file?

2018-04-12 Thread jfong
Chris Angelico於 2018年4月12日星期四 UTC+8下午1時31分35秒寫道:
> On Thu, Apr 12, 2018 at 2:16 PM,   wrote:
> > This C function returns a buffer which I declared it as a ctypes.c_char_p. 
> > The buffer has size 0x1 bytes long and the valid data may vary from a 
> > few bytes to the whole size.
> >
> > In every call I know how much the valid data size is, but I suppose I can't 
> > use slice to get it because there may be zero byte in it. What to do?
> >
> 
> You suppose? Or have you tested it?
> 
> ChrisA

Yes, I had test it once before. Now, I re-do it again to make sure. After a 
call which returns 3 bytes of data, I use len(buf) to check the length and get 
the number 24. I can see the first 24 bytes of data by using buf[:30] but 
buf[24] will cause an "index out of range" error. I don't know how to see what 
the buf[24] exactly is but I suppose it might be a zero byte.

--Jach
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How to write partial of a buffer which was returned from a C function to a file?

2018-04-11 Thread Chris Angelico
On Thu, Apr 12, 2018 at 2:16 PM,   wrote:
> This C function returns a buffer which I declared it as a ctypes.c_char_p. 
> The buffer has size 0x1 bytes long and the valid data may vary from a few 
> bytes to the whole size.
>
> In every call I know how much the valid data size is, but I suppose I can't 
> use slice to get it because there may be zero byte in it. What to do?
>

You suppose? Or have you tested it?

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list