Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

structures with functions and python ctypes

Tags:

python

c

ctypes

I have a c library I would like to wrap with python 2.7 ctypes.

typedef struct SRSLTE_API{
  void *ptr;
  uint32_t R;
  uint32_t K;
  uint32_t framebits;
  bool tail_biting;
  float gain_quant; 
  int16_t gain_quant_s; 
  int (*decode) (void*, uint8_t*, uint8_t*, uint32_t);
  int (*decode_f) (void*, float*, uint8_t*, uint32_t);
  void (*free) (void*);
  uint8_t *tmp;
  uint8_t *symbols_uc;
}srslte_viterbi_t;

How do I create this structure in python? This is what I currently have.

from ctypes import *
class srslte_viterbi_t(Structure):
    _fields_ = [("ptr", c_void_p),
                ("R", c_uint),
                ("K", c_uint),
                ("framebits", c_uint),
                ("tail_biting", c_bool),
                ("gain_quant", c_float),
                ("gain_quant_s", c_short),
                ("decode", POINTER(c_int)),
                ("decode_f", POINTER(c_int)),
                ("free", c_void_p),
                ("tmp", POINTER(c_ubyte)),
                ("symbols_uc", POINTER(c_ubyte))
                ]
viterbi_t = srslte_viterbi_t(None, c_uint(0), c_uint(0), c_uint(0), 
    c_bool(False), c_float(0.0), c_short(0), None, None, None, None, None)

This structure compiles but does not give the correct results. I fear I am not allocating the decode functions correctly? What is the line

int (*decode) (void*, uint8_t*, uint8_t*, uint32_t);

Doing in a structure anyway?

like image 706
Corey Hahn Avatar asked Jun 15 '17 02:06

Corey Hahn


People also ask

What does ctypes do in Python?

ctypes is a foreign function library for Python. It provides C compatible data types, and allows calling functions in DLLs or shared libraries. It can be used to wrap these libraries in pure Python.

Does ctypes work with C++?

ctypes is the de facto standard library for interfacing with C/C++ from CPython, and it provides not only full access to the native C interface of most major operating systems (e.g., kernel32 on Windows, or libc on *nix), but also provides support for loading and interfacing with dynamic libraries, such as DLLs or ...

What is C_char_p?

c_char_p is a subclass of _SimpleCData , with _type_ == 'z' . The __init__ method calls the type's setfunc , which for simple type 'z' is z_set . In Python 2, the z_set function (2.7. 7) is written to handle both str and unicode strings.


1 Answers

This is the correct definition of the struct:

from ctypes import *

class srslte_viterbi_t(Structure):
    _fields_ = [
        ('ptr',c_void_p),
        ('R',c_uint32),
        ('K',c_uint32),
        ('framebits',c_uint32),
        ('tail_biting',c_bool),
        ('gain_quant',c_float),
        ('gain_quant_s',c_int16),
        ('decode',CFUNCTYPE(c_int,c_void_p,POINTER(c_uint8),POINTER(c_uint8),c_uint32)),
        ('decode_f',CFUNCTYPE(c_int,c_void_p,POINTER(c_float),POINTER(c_uint8),c_uint32)),
        ('free',CFUNCTYPE(None,c_void_p)),
        ('tmp',POINTER(c_uint8)),
        ('symbols_uc',POINTER(c_uint8))]

viterbi_t = srslte_viterbi_t()

The structure is zero-initialized by ctypes when instantiated.

The decode line in the structure is a function pointer. CFUNCTYPE is used to define the function pointer return type and arguments.

like image 65
Mark Tolonen Avatar answered Sep 22 '22 17:09

Mark Tolonen