4

I need to learn how to handle the char** in the C++ method below through Python ctypes. I was doing fine calling other methods that only need single pointers by using create_string_buffer(), but this method requires a pointer to an array of pointers.

ladybugConvertToMultipleBGRU32(
         LadybugContext          context,
        const  LadybugImage * pImage,
        unsigned char**        arpDestBuffers,
         LadybugImageInfo *   pImageInfo  )

How do I create a pointer to an array of six create_string_buffer(7963648) buffers in ctypes to pass to this C++ method for writing?

arpDestBuffers = pointer to [create_string_buffer(7963648) for i in xrange(6)]

Thank you for any help.


Both the answers given below work. I just didn't realize I had another problem in my code which prevented me from seeing the results right away. The first example is just as Luc wrote:

SixBuffers = c_char_p * 6
arpDestBuffers = SixBuffers(
            *[c_char_p(create_string_buffer(7963648).raw) for i in xrange(6)] )

The second example coming from omu_negru's answer is:

arpDestBuffers = (POINTER(c_char) * 6)()
arpDestBuffers[:] = [create_string_buffer(7963648) for i in xrange(6)]

Both are accepted by the function and overwritten. Typing print repr(arpDestBuffers[4][:10]) before and after calling the function gives:

'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
'\x15\x10\x0e\xff\x15\x10\x0e\xff\x14\x0f'

which shows that the function successfully overwrote the buffer with data.

user6811
  • 417
  • 1
  • 6
  • 13

2 Answers2

1

Maybe Something like

SixBuffers = c_char_p * 6
arpDestBuffers = SixBuffers(*[c_char_p(create_string_buffer(7963648).raw) for i in xrange(6)])

Didin't try myself, so not sure that it works. Inspired by http://python.net/crew/theller/ctypes/tutorial.html#arrays

luc
  • 41,928
  • 25
  • 127
  • 172
  • Thanks. I tried it but it's not working for me. `SixBuffers = c_char_p * 6 arpDestBuffers = SixBuffers(*[c_char_p(create_string_buffer('\x00'*10).raw) for i in xrange(6)]) print type(arpDestBuffers), repr(arpDestBuffers) print type(arpDestBuffers[0]), repr(arpDestBuffers[0])` This has the following output: ` <__main__.c_char_p_Array_6 object at 0x01CB9F80> ''` – user6811 Jan 27 '12 at 13:06
  • What happens when your call your C API? The buffers is empty? Is it the problem? – luc Jan 27 '12 at 13:36
  • When passing the arpDestBuffers to the method, I get this error:`ctypes.ArgumentError: argument 2: : Don't know how to convert parameter 2` It's the same for most of the things I've tried. – user6811 Jan 27 '12 at 13:46
0

after you create all the string_buffers you need by calling create_string_buffer you can create an array for them with :

var=(POINTER(c_char)*size)()  /* pointer_to_pointer */

Then you can fill it up by indexing it with var[index] and finally just call your function using it as an argument.... Works fine for me and i just tested it on a function with the signature void test_fn(char*,char**,unsigned char); written in C

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
omu_negru
  • 4,642
  • 4
  • 27
  • 38
  • I guess I don't know enough about Python to implement what you suggested. Where does 'your_pointer_to_pointer' come from? Thanks – user6811 Jan 27 '12 at 13:11
  • sorry about that...was supposed to be a comment but i guess it just slipped....now it should be ok :) you make a new type (pointer array of size "size") and call the constructor and bind it to var. – omu_negru Jan 27 '12 at 14:05
  • To fill the var I have:`var[:] = [create_string_buffer(7963648) for i in xrange(6)]`. It seems that this var is what I want but I'm still getting a `ctypes.ArgumentError` when I try to pass it to the method. `ctypes.ArgumentError: argument 2: : Don't know how to convert parameter 2` – user6811 Jan 27 '12 at 14:49
  • The var did work! Thanks. I just found that `parameter 2` actually means the 2nd parameter. I assumed it meant the 3rd. So now both parameters are good now. – user6811 Jan 27 '12 at 15:17