4

I have a small application written in Python. It needs to take a user input(from cmd line):

def wr(input=0):   
    p = struct_t() # a C struct
    p.data = input # p.data is a pointer
    c_function(p)

Here data can be up to 32 words. And the data field of struct struct_t is of type uint32_t *.

The above code gives me an error of unmatched types for p.data = input. What I want is to have a buffer in Python that takes the user input and let the pointer p.data point to that buffer, so that I can pass p to my C routine.

I know that I can create a string buffer and cast it to type uint32_t * with ctypes in a very straightforward way, but I wonder if there's a way to do it in SWIG. Thanks a lot.

4
  • What do you want the type of input to be? It's easy if it's a list of ints. Commented Nov 18, 2014 at 8:26
  • @Flexo I think just ints, like input=479825793457392574390954370… (something very long, upto 32 words size) Thanks. Commented Nov 18, 2014 at 20:06
  • well that would never fit in a 32 bit int. Commented Nov 18, 2014 at 20:13
  • @rowan.G Yeah, thanks for pointing it out. Then I suppose it should be a list of ints. Thank you. Commented Nov 18, 2014 at 20:32

1 Answer 1

6
+50

To use SWIG to connect your Python script with C project, the first step is to create an interface file that includes the C functions that will be called by Python (i.e., interface functions), such as buffer.i as follows.

/* File: buffer.i */
%module buffer

%{
#define SWIG_FILE_WITH_INIT
#include "buffer.h"
%}

void wr(int idx, unsigned int val);
unsigned int rd(int idx);

It's a good practice to keep the interface simple, and leave the complexity to C running in the background. Accordingly, you can manually create a C header file (buffer.h) and implementation file (buffer.c), as follows.

Here is buffer.h

/* File: buffer.h */

#include <stdint.h>

void wr(int idx, unsigned int val);
unsigned int rd(int idx);

Here is buffer.c

/* File: buffer.c */

#include "buffer.h"

#define BUF_SIZE 32

unsigned int buf[BUF_SIZE];

void wr(int idx, unsigned int val) {
  buf[idx%BUF_SIZE] = val;
}

unsigned int rd(int idx) {
  return buf[idx%BUF_SIZE];
}

And you'll need a setup file (setup.py):

#!/usr/bin/env python

"""
setup.py file for SWIG buffer
"""

from distutils.core import setup, Extension


buffer_module = Extension('_buffer',
                           sources=['buffer_wrap.c', 'buffer.c'],
                           )

setup (name = 'buffer',
       version = '0.1',
       author      = "SWIG Docs",
       description = """Simple swig buffer from docs""",
       ext_modules = [buffer_module],
       py_modules = ["buffer"],
       )

Now you can use SWIG to build the project by issuing the following commands:

$ swig -python buffer.i
$ python setup.py build_ext --inplace

The above commands will automatically generate buffer.py, which give you the caller framework (on Python side). Open this file, you'll see _buffer.wr and _buffer.rd already being created. In order to convert a very long int (Python style) 32 bits at a time and keep it in a C array, you can add a wrapper function in buffer.py, which calls the automatically generated Python function wr multiple times:

def wr1(args):
  for n in range(0, 32):
    val = args & 0xffffffff
    wr(n, val)
    args >>= 32
    if args == 0:
      break

Now you can run Python. Here is what you see when you run it:

>>> import buffer
>>> buffer.wr1(0x12345678deadbeef)
>>> hex(buffer.rd(0))
'0xdeadbeef'
>>> hex(buffer.rd(1))
'0x12345678'
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you for the answer. But can you explain what is _buffer.wr and _buffer.rd? I still don't know how the c function is connected with Python. I don't need to modify the .i file for SWIG?
@JFreebird: Updated by giving more details.
BTW, here is a link to describe using SWIG for Python:swig.org/Doc1.3/Python.html

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.