2

I have the code in C:

typedef result function_callback(struct mes_t* message, void* data) 
struct mes_t
{
uint32_t field1
uint32_t field2
void* data
};
function_one(&function_callback, data)

The application calls the user-defined (in the function_one) callback function function_callback. In the callback function passed field1, field2 and data parameters (data is usually equal to 0)

Whether the code on a python for this example is correctly written?

class mes_t(ctypes.Structure):
    pass
mes_t._fields_ = [
    ('field1', ctypes.c_uint32),
    ('dfield2', ctypes.c_uint32),
    ('data', ctypes.POINTER(ctypes.c_void_p))]
data_t=ctypes.c_void_p
data=data_t()
CALLBACK=CFUNCTYPE(ccg_msg, data_t)
cb_func=CALLBACK()
result = function_one(ctypes.byref(cb_func), ctypes.byref(data))
1
  • It may help to fix your sample code; the C declarations are invalid (I am guessing you're just missing some semicolons and putting things in the wrong order) and it's not clear what ccg_msg is. Commented May 24, 2012 at 15:09

1 Answer 1

1

I've guessed here the right way to interpret your code. Adjusted sample snippets here:

typedef int /* or whatever */ result;

struct mes_t
{
    uint32_t field1;
    uint32_t field2;
    void* data;
};
typedef result function_callback(struct mes_t* message, void* data);
result function_one(function_callback fcb, void* data);

And here's some example ctypes Python for making use of function_one():

class mes_t(ctypes.Structure):
    _fields_ = (
        ('field1', ctypes.c_uint32),
        ('field2', ctypes.c_uint32),
        ('data', ctypes.c_void_p))

result_t = ctypes.c_int; # or whatever

callback_type = ctypes.CFUNCTYPE(result_t, ctypes.POINTER(mes_t), ctypes.c_void_p)
function_one.argtypes = (callback_type, ctypes.c_void_p)
function_one.restype = result_t

data_p = ctypes.c_char_p('whatever')

def the_callback(mes_p, data_p):
    my_mes = mes_p[0]
    my_data_p = ctypes.cast(data_p, ctypes.c_char_p)  # or whatever
    my_data = my_data_p.value
    print "I got a mes_t object! mes.field1=%r, mes.field2=%r, mes.data=%r, data=%r" \
          % (my_mes.field1, my_mes.field2, my_mes.data, my_data)
    return my_mes.field1

result = function_one(callback_type(the_callback), ctypes.cast(data_p, ctypes.c_void_p))

You'll see there are numerous differences between this and your code; probably too much to give full explanations of everything. I can, however, explain a few particular parts if there are some which seem especially confusing. In general, though, it's important to have a good understanding of how ctypes pointers work (for example, you probably don't want a pointer to a pointer to void, but that's what your python code did).

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.