在 python 中调用 C 程序函数 - 分段错误

calling C program function in python - Segmentation fault

所以我有一个来自 Python 的 C 程序 运行ning。但是我收到分段错误错误。当我单独 运行 C 程序时,它 运行 没问题。 C 程序使用 fprint 库连接指纹传感器。

#include <poll.h>
#include <stdlib.h>
#include <sys/time.h>
#include <stdio.h>
#include <libfprint/fprint.h>



int main(){

struct fp_dscv_dev **devices;
struct fp_dev *device;
struct fp_img **img;

int r;
r=fp_init();

if(r<0){
    printf("Error");
    return 1;
}

devices=fp_discover_devs();
if(devices){
    device=fp_dev_open(*devices);

    fp_dscv_devs_free(devices);
}
if(device==NULL){
    printf("NO Device\n");
    return 1;
}else{
    printf("Yes\n");
   
}


int caps;

caps=fp_dev_img_capture(device,0,img);

printf("bloody status %i \n",caps);

    //save the fingerprint image to file. ** this is the block that 
     causes the segmentation fault.

    int imrstx;
    imrstx=fp_img_save_to_file(*img,"enrolledx.pgm");
    fp_img_free(*img);


fp_exit();
return 0;
}

python代码

from ctypes import *
so_file = "/home/arkounts/Desktop/pythonsdk/capture.so"
my_functions = CDLL(so_file)

a=my_functions.main()
print(a)
print("Done")

capture.so 在 python 中构建和访问。但是从 python 调用时,我遇到了分段错误。我的问题是什么?

非常感谢

虽然我不熟悉 libfprint,但在查看您的代码并将其与文档进行比较后,我发现您的代码有两个问题都可能导致分段错误:


第一期:

根据documentation of the function fp_discover_devs,错误返回NULL。成功时,返回一个以 NULL 结尾的列表,它可能是空的。

在以下代码中,您检查 failure/success,但不检查空列表:

devices=fp_discover_devs();
if(devices){
    device=fp_dev_open(*devices);

    fp_dscv_devs_free(devices);
}

如果 devices 非 NULL,但为空,则 devices[0](相当于 *devices)为 NULL。在这种情况下,您将此 NULL 指针传递给 fp_dev_open。这可能会导致分段错误。

不过我认为这不是您的分段错误的原因,因为您的代码中的这个错误只会在返回空列表时触发。


第二期:

fp_dev_img_capture 的最后一个参数应该是指向 分配的 类型 struct fp_img * 变量的指针。这告诉函数它应该写入的变量的地址。但是,使用代码

struct fp_img **img;
[...]
caps=fp_dev_img_capture(device,0,img);

您正在向该函数传递 wild pointer, because img does not point to any valid object. This can cause a segmentation fault as soon as the wild pointer is dereferenced by the function or cause some other kind of undefined behavior,例如覆盖您程序中的其他变量。

我建议您改为编写以下代码:

struct fp_img *img;
[...]
caps=fp_dev_img_capture(device,0,&img);

现在第三个参数指向一个有效的对象(指向变量img)。

由于 img 现在是单指针而不是双指针,您必须将 img 而不是 *img 传递给函数 fp_img_save_to_filefp_img_free.

第二个问题可能是您的分段错误的原因。看起来你只是“幸运”你的程序没有作为独立程序出现段错误。