Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用CFFI包装C-DLL以回调python_Python_C_Callback_Wrapper_Python Cffi - Fatal编程技术网

如何使用CFFI包装C-DLL以回调python

如何使用CFFI包装C-DLL以回调python,python,c,callback,wrapper,python-cffi,Python,C,Callback,Wrapper,Python Cffi,我目前正试图包装一个c-dll来控制通过USB连接的摄像头。为了从相机中获取图像数据,SDK提供商(Thorlabs)介绍了两种可能性: 以循环方式轮询摄影机 使用回调 我包装了DLL并使轮询方法开始工作,它基本上包括调用一个返回NULL或挂起帧的方法 DLL还提供了将回调函数分配给某些事件的方法,例如相机连接/断开和帧可用。示例中的C代码如下所示: void camera_connect_callback(char* cameraSerialNumber, enum USB_PORT_TY

我目前正试图包装一个c-dll来控制通过USB连接的摄像头。为了从相机中获取图像数据,SDK提供商(Thorlabs)介绍了两种可能性:

  • 以循环方式轮询摄影机
  • 使用回调
我包装了DLL并使轮询方法开始工作,它基本上包括调用一个返回NULL或挂起帧的方法

DLL还提供了将回调函数分配给某些事件的方法,例如相机连接/断开和帧可用。示例中的C代码如下所示:

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;
    }

    [...]
}
我现在的目标是让回调与python一起工作,以便从dll调用python方法。因此,我在API模式下使用CFFI编译包装器,然后尝试以相同的方式将回调方法传递给DLL:

@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)))

[...]
出于测试目的,我在工作轮询示例中只包含了最简单的回调。setter方法返回0,但从未执行该方法

这是实现我目标的正确方式吗?我是否需要引入某种线程,以便回调可以中断剩余程序的顺序执行? 关于这个主题没有太多的文档或例子,所以我真的希望你们能帮助我

编辑

因此,我尝试了一个非常基本的例子,从技术上回答了我的问题,但没有解决我的问题

如果我定义一个C回调方法,如下所示:

#include <math.h>

int quadcalc(int input, int (*getval)(int)){
    return (int) pow(getval(input), 2);
}
一切都按预期进行。不幸的是,这对实际问题不起作用。所以回调在一般情况下有效,但在特定情况下无效,这就是问题仍然存在的原因。

我是否需要引入某种线程,以便回调可以中断剩余程序的顺序执行

调用回调方法需要设置备用程序流来捕获事件,以便将其路由到要处理的处理程序。当定义的事件发生时,它确实需要处理程序代码。例如,这里有一个非常通用但完整的(包括handler函数):

void填充数组(int*array,size\t arraySize,int(*getNextValue)(void))
{
对于(尺寸i=0;i

除此之外,还有一个很好的教程,第一节专门讨论如何使用CFFI包装C-DLL以回调python的标题问题:

第一部分给出了一个简单的工作示例,使用CFFI从Python中调用编译的共享对象(DLL)中的C函数

步骤如下:(有关每个步骤的详细信息,请参见上面的链接。)
-创建文件piapprox\u build.py:
-执行此脚本:
-在运行时,您可以像这样使用扩展模块:

…在本页的其余部分,我们将介绍更多内容 高级示例和其他CFFI模式


谢谢你的回答!说得清楚一点,我让DLL包装部分正常工作,我可以调用C-header中为DLL定义的任何方法。我根本无法让回调正常工作。我发布的C代码示例在编译时也能正常工作,但python方法作为回调的分配并没有像我所希望的那样正常工作。我非常满意re It’s just Error Implementation是由供应商SDK提供商(Thorlabs)提供的回调,还是您需要定义它们?@user3183627-看看。它指的是Thorlabs,以及回调的使用。它可能提供了一些见解。Thorlabs SDK提供了“set_callback_xxx”方法。在标题中可以找到以下类型定义:
typedef void(*TL\u CAMERA\u CONNECT\u回调)(char*cameraSerialNumber,enum TL\u CAMERA\u USB\u PORT\u TYPE USB\u PORT\u PORT\u TYPE,void*context);
typedef int(*TL\u CAMERA\u SET\u CAMERA\u CONNECT\u回调)(TL\u CAMERA\u CONNECT回调处理程序,void*context);
在我在上面的回答中提供的示例代码中,如果在该库中找到正确的installCallback方法,则只有回调处理程序函数才适用。例如,在我使用的环境中,我只需调用提供的函数来创建回调,例如:CreateComCallback(,,,,,handlerFunction,,);为我创建一个实例。我所要做的就是创建处理程序函数。这似乎是您需要做的。(即:1)从所选的固定回调中调用正确的installCallback函数。2)定义处理程序函数。)
@ffi.callback("int(int)")
def callback_func(value):
    return int(rnd.random() * value)


if __name__ == '__main__':
    print(lib.quadcalc(10, callback_func))
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);
    ...
}