简体   繁体   中英

How to make a C-DLL wrapped with CFFI to callback python

I am currently trying to wrap a c-dll to controll a camera connected via USB. To grab image data off the camera, the SDK-Provider (Thorlabs) describes two possibilities:

  • Poll the camera in a loop
  • Use callbacks

I wrapped the DLL and got the polling method to work, which basically consists of calling a method which returns either NULL or the pending frame.

The DLL also provides methods to assign callback functions to certain events, such as camera connected/disconnected and frame available. The C-code from the example looks like this:

void camera_connect_callback(char* cameraSerialNumber, enum USB_PORT_TYPE usb_bus_speed, void* context)
{
    printf("camera %s connected with bus speed = %d!\n", cameraSerialNumber, usb_bus_speed);
}


int main(void)
{

    [...]

    // Set the camera connect event callback. This is used to register for run time camera connect events.
    if (tl_camera_set_camera_connect_callback(camera_connect_callback, 0))
    {
        printf("Failed to set camera connect callback!\n");
        close_sdk_dll();
        return 1;
    }

    [...]
}

My goal is now to get the callback working with python, so that python methods are called from the dll. Therefore, I used CFFI in API-mode to compile the wrapper, then tried to pass a callback method to the DLL in the same fashion:

@ffi.callback("void(char*, void*)")
def disconnect_callback(serialNumber, context):
    print("Disconnect callback was called!")

[...]

print("Set disconnect callback: {}".format(lib.tl_camera_set_camera_disconnect_callback(disconnect_callback, ffi.NULL)))

[...]

For testing purposes I only included the simplest callback in the working polling example. The setter method returns 0 but the method is never executed.

Is this even the right way of accomplishing my goal? Do I need to introduce some kind of threading so that the callback can interrupt the sequential execution of the remaining program? There is not much documentation or examples on this topic so Im really hoping you guys can help me out.

EDIT

So I tried a very basic example which works and technically answeres my question, but does not solve my problem.

if I define a C callback method as follows:

#include <math.h>

int quadcalc(int input, int (*getval)(int)){
    return (int) pow(getval(input), 2);
}

I can assign a handler as expected: (After compiling of course)

@ffi.callback("int(int)")
def callback_func(value):
    return int(rnd.random() * value)


if __name__ == '__main__':
    print(lib.quadcalc(10, callback_func))

And everything works as expected. Unfortunately, this doesn't work on the actual Problem. So callback works in general, but not in the specific case, which is why the question is still open.

Do I need to introduce some kind of threading so that the callback can interrupt the sequential execution of the remaining program?

Invoking the Callback method takes care of setting up alternate program flows to capture the event, so it can be routed to a handler to be processed. When the defined event occurs, it does need handler code. For example, here is a very generic, but complete example of code that uses a callback in C (including the handler function.):

void populate_array(int *array, size_t arraySize, int (*getNextValue)(void))
{
    for (size_t i=0; i<arraySize; i++)
        array[i] = getNextValue();
}

// handler function
int getNextRandomValue(void)
{
    return rand();
}

int main(void)
{
    int myarray[10];
    populate_array(myarray, 10, getNextRandomValue);
    ...
}

There is an equally good example just below the first one, here .

Beyond these, there is a good tutorial in the CFFI documentation , with the first section dedicated to addressing your title question How to make a C-DLL wrapped with CFFI to callback python :

The first section presents a simple working example of using CFFI to call a C function in a compiled shared object (DLL) from Python .

Steps are: (see link above for details of each step.)
- Create the file piapprox_build.py:
- Execute this script:
- At runtime, you use the extension module like this:

...In the rest of this page, we describe some more advanced examples and other CFFI modes...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM