ctypes and how to copy data passed to callback

W

waldek

Hi,

I'm trying to handle data passed to Py Callback which is called from
C dll. Callback passes data to another thread using Queue module and
there the data are printed out.

If data is printed out in a callback itself it's ok. If I put on
queue and next get from queue in another thread script prints some
trash. Looks like the data is released when callback returned. I tired
to make d = copy.deepcopy(data), but it does not work - I got nothing.
Any idea why it's happening ?

--------------------- main thread --------
def callback(data, size):
myqueue.put((data, size))

mydll = cdll.MyDLL
cbproto = CFUNCTYPE(c_int, POINTER(c_char), c_int)
mycallback = cbproto(callback)

mydll.RegisterCallback(mycallback)

---------------------------------- thread listener
----------------------

while True:
data, size = myqueue.get()
print "***", data[:size]

------------------------------------------------------------------------------
 
D

Diez B. Roggisch

waldek said:
Hi,

I'm trying to handle data passed to Py Callback which is called from
C dll. Callback passes data to another thread using Queue module and
there the data are printed out.

If data is printed out in a callback itself it's ok. If I put on
queue and next get from queue in another thread script prints some
trash. Looks like the data is released when callback returned. I tired
to make d = copy.deepcopy(data), but it does not work - I got nothing.
Any idea why it's happening ?

--------------------- main thread --------
def callback(data, size):
myqueue.put((data, size))

mydll = cdll.MyDLL
cbproto = CFUNCTYPE(c_int, POINTER(c_char), c_int)
mycallback = cbproto(callback)

mydll.RegisterCallback(mycallback)

---------------------------------- thread listener
----------------------

while True:
data, size = myqueue.get()
print "***", data[:size]

------------------------------------------------------------------------------

You need to allocate e.g. a bytebuffer using ctypes and then copy the memory
area you get passed into that buffer.

Otherwise I presume whoever invokes the callback releases the originaly
memory block after the callback terminated.

Diez
 
T

Thomas Heller

waldek said:
Hi,

I'm trying to handle data passed to Py Callback which is called from
C dll. Callback passes data to another thread using Queue module and
there the data are printed out.

If data is printed out in a callback itself it's ok. If I put on
queue and next get from queue in another thread script prints some
trash. Looks like the data is released when callback returned. I tired
to make d = copy.deepcopy(data), but it does not work - I got nothing.
Any idea why it's happening ?

--------------------- main thread --------
def callback(data, size):
myqueue.put((data, size))

mydll = cdll.MyDLL
cbproto = CFUNCTYPE(c_int, POINTER(c_char), c_int)
mycallback = cbproto(callback)

mydll.RegisterCallback(mycallback)

---------------------------------- thread listener
----------------------

while True:
data, size = myqueue.get()
print "***", data[:size]

------------------------------------------------------------------------------

I guess your code would work if you change it in this way:
def callback(data, size):
myqueue.put(data[:size])
while True:
data = myqueue.get()
print "***", data

Thomas
 
W

waldek

waldek schrieb:


I'm trying to handle data passed to Py Callback which is called from
C dll. Callback passes data to another thread using Queue module and
there the data are printed out.
If data is printed out in a callback itself it's ok. If I put on
queue and next get from queue in another thread script prints some
trash. Looks like the data is released when callback returned. I tired
to make d = copy.deepcopy(data), but it does not work - I got nothing.
Any idea why it's happening ?
--------------------- main thread --------
def callback(data, size):
myqueue.put((data, size))
mydll = cdll.MyDLL
cbproto = CFUNCTYPE(c_int, POINTER(c_char), c_int)
mycallback = cbproto(callback)

---------------------------------- thread listener
----------------------
while True:
data, size = myqueue.get()
print "***", data[:size]
------------------------------------------------------------------------------

I guess your code would work if you change it in this way:
def callback(data, size):
myqueue.put(data[:size])
while True:
data = myqueue.get()
print "***", data

Thomas

Both solutions work fine. The secon is nicer :)

Thanks
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,190
Members
46,736
Latest member
zacharyharris

Latest Threads

Top