使用ctypes从Python中C函数返回的结构访问数据 [英] Accessing data from a structure returned by C function in Python using ctypes

查看:157
本文介绍了使用ctypes从Python中C函数返回的结构访问数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道这个问题已经得到治疗,但是我找不到适合我的东西,所以我想我的问题与其他问题略有不同。

I know the subject has already been treated, but I've failed to find anything that works for me, so I guess my problem is slightly different from the others.

基本上,我的工作是使用C函数将C函数包装到python代码中。
我的目标是在C函数中计算一些量,将它们存储到单个结构中,然后在Python中返回该结构,以便在其中读取该结构中的所有不同数据。

What I do, basically, is that I use a C function wrapped into a python code using ctypes. My goal is to compute some quantities in the C function, store them into a single structure, and return the structure in Python where I could read all the different data in the structure.

所以:

要在python中定义我的结构,我使用:

To define my structure in python, I use :

class BITE(ctypes.Structure):
    _fields_ = [
                ("lum", ctypes.c_int),
                ("suce", ctypes.c_int)
                ]

我这样编译:

sub.call(["gcc","-shared","-Wl,-install_name,ex.so","-o","ex.so","-fPIC","ex.c"])


lum = ctypes.CDLL('ex.so')
lum = lum.lum

我声明这样的参数和结果类型:

I declare the arguments and result types like this :

lum.restype = ctypes.POINTER(BITE)
lum.argtypes = [ctypes.POINTER(ctypes.c_float),ctypes.c_int,ctypes.POINTER(ctypes.c_float),ctypes.c_int,ctypes.POINTER(ctypes.c_float),ctypes.POINTER(ctypes.c_float),ctypes.c_int,ctypes.POINTER(ctypes.c_float),ctypes.c_int,ctypes.POINTER(ctypes.c_float),ctypes.POINTER(ctypes.c_float),ctypes.POINTER(ctypes.c_float),ctypes.POINTER(ctypes.c_float),ctypes.c_float,ctypes.c_float,ctypes.c_float,ctypes.c_float,ctypes.c_float]

然后,我在python代码中将C函数称为 lum

Then, I call the C function "lum" in the python code

out = lum(all the different variables needed)

问题从这里开始。我有自己的结构,但无法读取每个字段中存储的数据。

The problem begins here. I have my structure, but impossible to read the data stored in each fields.

我发现的部分解决方案是:

A partial solution I found is to do :

out = out[0]

但是然后,当执行

print(out.suce)

我有一个细分错误11.不知道为什么。我试图了解如何使用create_string_buffer,但我并没有真正了解它的工作原理和功能。而且,我试图用作黑匣子,但仍然没有任何效果。

I have a segmentation fault 11. DOn't know why. I tried to understand how to used create_string_buffer, but I didn't really understand how it works and what it supposed to do. Moreover, I tried to using as a black box, and still, nothing works.

我还尝试了其他线程中提到的其他解决方案,例如使用out.contents之类的东西那样,但是它没有.contents属性。也没有out.suce.value,这也是我在绝望的研究中看到的东西。

I also tried some other solutions mentionned in other threads such as using out.contents or something like that, but it has no .contents attributes. Nor out.suce.value, which is also something I saw somewhere during my desperate research.

当然,我在C代码中检查了结构的存在以及每个结构的存在。该结构的字段存在,并且其中包含正确的数据。

Of course, I checked in the C code that the structure exists and that each field of the structure exists, and has the right data in it.

谢谢。

推荐答案

假设您具有这样的C结构:

Suppose you have a C-structure like this :

typedef struct _servParams
{
   unsigned short m_uServPort;
   char m_pInetAddr[MAX_LENGTH_OF_IP_ADDRESS];
} ServerParams_t;

要在ctypes中使用它,您应该创建一个这样的包装器:

To use it within ctypes you should create a wrapper like this :

class ServerParams_t(Structure):
        _fields_ = [    ("m_uServPort", c_ushort),
                        ("m_pInetAddr", (c_char * 16)) ]

稍后在python中,您可以使用以下代码段:

Later on inside your python you can use the following snippet :

servParams = ServerParams_t()
servParams.m_uServPort = c_ushort(int(port))
servParams.m_pInetAddr = ip.encode()

如果需要按值传递,只需传递 servParams 您的api变量。如果需要传递指针,请使用 byref(servParams)

If you need to pass it by value, simply pass servParams variable to you api. If you need to pass a pointer use byref(servParams).

这篇关于使用ctypes从Python中C函数返回的结构访问数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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