简体   繁体   English

如何在python中传递包含自定义数据类型的C结构

[英]How to pass C structure containing custom defined datatypes in python

I'm am writing in python code first time.我是第一次用python代码编写。 Wanted to call C shared library function from python, however problem is unable to pass structure containing custom data types.想从 python 调用 C 共享库函数,但是问题是无法传递包含自定义数据类型的结构。

mylib.c mylib.c

#include <stdio.h>
  
typedef int             integer;
typedef char            character;

struct temp {
        integer         a;
        character       b;
};

void
do_something(
        struct temp     *abc)
{
        abc->a = 100;
        abc->b = 'M';
        return;
}

Compilation step编译步骤

# gcc -fPIC -shared -o mylib.so mylib.c 

Please consider interger and character as some other user defined datatypes, though in above example they are typedef of primitive datatypes int and char, but in my situation they are not, there is 2 or 3 level of indirection for various situations like if machine is 32bit or 64bit, or if working on solaris, AIX, or Linux etc..请考虑将整数和字符视为其他一些用户定义的数据类型,尽管在上面的示例中它们是原始数据类型 int 和 char 的 typedef,但在我的情况下它们不是,对于各种情况,例如机器是 32 位,有 2 或 3 级间接性或 64 位,或者如果在 solaris、AIX 或 Linux 等上工作。

I have written one sample python program also which is working fine if I use ctypes.c_int and ctypes.c_char, but I want to use integer and character custom datatypes inside python code.我编写了一个示例 python 程序,如果我使用 ctypes.c_int 和 ctypes.c_char,它也可以正常工作,但我想在 python 代码中使用整数字符自定义数据类型。 Basically wanted to write python code as it does not depend on actual primitive types.基本上想编写python代码,因为它不依赖于实际的原始类型。

Python3 program Python3程序

import ctypes 
        
class sample(ctypes.Structure):
    _fields_ = [
            ("a", ctypes.c_int),
            ("b", ctypes.c_char)]

s = sample()
    
do_something = ctypes.CDLL("/root/Documents/python/mylib.so").do_something
do_something.argtypes = [ctypes.POINTER(sample)]
    
do_something(s)
    
print(s.a)
print(s.b)

Output:输出:

100
b'M'

Thank you!谢谢!

Responding to @Mark Tolonen queries回复@Mark Tolonen 查询


Though I cannot paste actual code, but below code is quite similar to actual one, here struct is having field of pid_t (though it is currently integer type internally, but relying on this fact is not good I think), timeval structure, and filesize which can be changed based on OFFSET64 declaration.虽然我无法粘贴实际代码,但下面的代码与实际代码非常相似,这里的 struct 具有 pid_t 字段(虽然它目前在内部是整数类型,但我认为依靠这个事实并不好)、timeval 结构和文件大小可以根据 OFFSET64 声明进行更改。

I want struct info (allocated inside python code) to get filled from C library.我希望从 C 库中填充结构信息(在 python 代码中分配)。

#include <unistd.h>
#include <sys/time.h>

typedef unsigned int            __filesize;
typedef unsigned long long      __filesize64;
typedef unsigned long           inode_t;
#ifndef OFFSET64
typedef __filesize              filesize;
#endif
#ifdef  OFFSET64
typedef __filesize64            filesize;
#endif

struct info {
        pid_t           pid;
        struct timeval  atime;
        filesize        sz;
        inode_t         i_number;
};

void
did_something(
        struct info *p_info)
{
        p_info->pid = getpid();
        gettimeofday(&p_info->atime, NULL);

        p_info->sz = 512;
        p_info->i_number = 2;

        return;
}

I didn't go digging up the definitions of pid_t , timeval , or inode_t but since filesize definition was provided here's a way to define it:我没有去挖掘pid_ttimevalinode_t的定义,但由于这里提供了filesize定义,因此有一种方法来定义它:

OFFSET64 = True # or False

if OFFSET64:
    filesize = ctypes.c_ulonglong
else:
    filesize = ctypes.c_uint

Then use filesize in the class definition for the structure:然后在结构的类定义中使用filesize

class info(ctypes.Structure):
    _fields_ = (...
                ('sz', filesize),
                ...)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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