Re: How to write partial of a buffer which was returned from a C function to a file?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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