在Python中调用C函数并返回2个值 [英] Calling a C function in Python and returning 2 values

查看:231
本文介绍了在Python中调用C函数并返回2个值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图弄清楚如何从我在python中调用的C函数返回2个值。我已经在线阅读了该材料,并正在使用struct输出两个变量。当我在同一C文件中调用此函数时,我能够输出变量。但是,当我尝试在python中调用它时,它仍然只返回一个值。

I am trying to figure out how to return 2 vales from a C function that I called in python. I have read through the material online and am using struct to output the two variables. I am able to output the variables when I call this function in the same C file. However, when I try to call it in python, it still only returns one value.

这是我的C代码:

struct re_val {

    double predict_label;
    double prob_estimates;  

};

struct re_val c_func(const char* dir, double a, double b, double c, double d )
{
    double x[] = {a,b,c,d};

    printf ("x[0].index: %d \n", 1);
    printf ("x[0].value: %f \n", x[0]);

    printf ("x[1].index: %d \n", 2);
    printf ("x[1].value: %f \n", x[1]);

    printf ("x[2].index: %d \n", 3);
    printf ("x[2].value: %f \n", x[2]);

    printf ("x[3].index: %d \n", 4);
    printf ("x[3].value: %f \n", x[3]);

    printf ("\nThis is the Directory: %s \n", dir); 

    struct re_val r;
    r.predict_label = 5.0;
    r.prob_estimates = 8.0;   

    return r;

}

这是我的Python代码:

This is my Python code:

calling_function = ctypes.CDLL("/home/ruven/Documents/Sonar/C interface/Interface.so")
calling_function.c_func.argtypes = [ctypes.c_char_p, ctypes.c_double, ctypes.c_double, ctypes.c_double, ctypes.c_double]
calling_function.c_func.restype =  ctypes.c_double
q = calling_function.c_func("hello",1.3256, 2.45, 3.1248, 4.215440)
print q

当前,当我运行python文件时在终端中,它输出以下内容:

Currently, when I run my python file in the terminal it outputs this:

x[0].index: 1 
x[0].value: 1.325600 

x[1].index: 2 
x[1].value: 2.450000 

x[2].index: 3 
x[2].value: 3.124800 

x[3].index: 4 
x[3].value: 4.215440 

This is the Directory: hello 

5.0

相反,我希望它输出:

x[0].index: 1 
x[0].value: 1.325600 

x[1].index: 2 
x[1].value: 2.450000 

x[2].index: 3 
x[2].value: 3.124800 

x[3].index: 4 
x[3].value: 4.215440 

This is the Directory: hello 

5.0
8.0


推荐答案

您的C代码很好,您遇到的问题是如何使用python ctypes。您应该告诉该函数返回 struct re_val 而不是双精度值:

Your C code is fine, the problem you are experiencing is in how you use python ctypes. You should tell that the function returns a struct re_val and not a double:

calling_function.c_func.restype =  ctypes.c_double

上面的方法使函数返回单个双精度值在ctypes的眼中。您应该告诉python函数返回一个结构:

The above makes the function return a single double value in the eyes of ctypes. You should tell python that the function returns a structure:

import ctypes as ct

# Python representation of the C struct re_val
class ReVal(ct.Structure):
    _fields_ = [("predict_label", ct.c_double),("prob_estimates", ct.c_double)]

calling_function = ctypes.CDLL("/home/ruven/Documents/Sonar/C interface/Interface.so")
calling_function.c_func.argtypes = [ctypes.c_char_p, ctypes.c_double, ctypes.c_double, ctypes.c_double, ctypes.c_double]
# and instead of c_double use:
calling_function.c_func.restype = ReVal

通过这种方式告诉python的ctypes函数返回一个聚合对象,该对象是ctypes的子类。结构与c中的 struct re_val 相匹配

This way you tell python's ctypes that the function returns a aggregate object that is a subclass of ctypes.Structure that matches the struct re_val from the c library.

注意,请务必谨慎使用argtypes和restype,如果使用不当,很容易使python解释器崩溃。然后,您将得到一个段错误而不是很好的回溯。

NOTE Be very carefull with argtypes and restype, if you use these incorrectly it is easy to crash the python interpreter. Then you get a segfault instead of a nice traceback.

这篇关于在Python中调用C函数并返回2个值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆