C to python conversion

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Michele Petrazzo

    C to python conversion

    Hi all,
    I'm trying to translate a simple C code into a python + ctypes (where
    need), but I have some problems on char conversion. The code have
    to work on Linux and talk with the serial port. I think that the problem
    is that I don't translate correctly the strings.

    C code:
    #define START 0x33
    #define RETURN_START 0x22
    #define ADDR 0x01
    #define WRITE_CMD 0x03
    #define ALL_CMD 0xFF
    ....
    char buf[10];
    char buf_ret[10];

    buf[0]=0;
    buf[0]=START;
    buf[1]=ADDR;
    buf[2]=WRITE_CMD;

    write(_fd, buf, 6);
    read(_fd,buf_re t,6);

    It works

    python:
    START = 0x33
    RETURN_START = 0x22
    ADDR = 0x01
    WRITE_CMD = 0x03
    ALL_CMD = 0xFF

    lib = C.CDLL('libc.so .6')

    items = [START, ADDR, WRITE_CMD]
    buf = C.c_char * 10
    buffer_rec = buf()
    buffer_send = buf(*items)

    (Here I receive: TypeError: one character string expected)
    If I do:
    chr(int()) of every value, it work, but:

    lib.write(fd, buffer_send, 6)
    lib.read(fd, buffer_rec, 6)

    I stay there and block the program execution, until a CTRL+C

    What can I do?

    Thanks,
    Michele
  • Paul McGuire

    #2
    Re: C to python conversion

    On Apr 12, 5:58 am, Michele Petrazzo <michele.petra. ..@TOGLIunipex. it>
    wrote:
    Hi all,
    I'm trying to translate a simple C code into a python + ctypes (where
    need), but I have some problems on char conversion. The code have
    to work on Linux and talk with the serial port. I think that the problem
    is that I don't translate correctly the strings.
    >
    C code:
    #define START 0x33
    #define RETURN_START 0x22
    #define ADDR 0x01
    #define WRITE_CMD 0x03
    #define ALL_CMD 0xFF
    ...
    char buf[10];
    char buf_ret[10];
    >
    buf[0]=0;
    buf[0]=START;
    buf[1]=ADDR;
    buf[2]=WRITE_CMD;
    >
    write(_fd, buf, 6);
    read(_fd,buf_re t,6);
    >
    It works
    >
    python:
    START = 0x33
    RETURN_START = 0x22
    ADDR = 0x01
    WRITE_CMD = 0x03
    ALL_CMD = 0xFF
    >
    lib = C.CDLL('libc.so .6')
    >
    items = [START, ADDR, WRITE_CMD]
    buf = C.c_char * 10
    buffer_rec = buf()
    buffer_send = buf(*items)
    >
    (Here I receive: TypeError: one character string expected)
    If I do:
    chr(int()) of every value, it work, but:
    >
    lib.write(fd, buffer_send, 6)
    lib.read(fd, buffer_rec, 6)
    >
    I stay there and block the program execution, until a CTRL+C
    >
    What can I do?
    >
    Thanks,
    Michele
    Here are some differences between the C and Python programs:
    - the C program uses a separate buffer for reading and writing - the
    Python program uses buf for both
    - the C program *may* have null-filled the output buffer, I don't know
    what the Python buffer contains after the first 3 characters
    - in the Python program, items has only 3 characters to write; the C
    program has a buffer of 10 characters

    Here are some things to try in the Python program:

    items = [START, ADDR, WRITE_CMD] + [0]*7

    inbuf = C.c_char * 10
    outbuf = C.c_char * 10
    buffer_rec = inbuf()
    buffer_send = outbuf(*items)

    -- Paul

    Comment

    • Gabriel Genellina

      #3
      Re: C to python conversion

      En Sat, 12 Apr 2008 07:58:47 -0300, Michele Petrazzo
      <michele.petraz zo@TOGLIunipex. itescribió:
      Hi all,
      I'm trying to translate a simple C code into a python + ctypes (where
      need), but I have some problems on char conversion. The code have
      to work on Linux and talk with the serial port. I think that the problem
      is that I don't translate correctly the strings.
      >
      C code:
      #define START 0x33
      #define RETURN_START 0x22
      #define ADDR 0x01
      #define WRITE_CMD 0x03
      #define ALL_CMD 0xFF
      ...
      char buf[10];
      char buf_ret[10];
      >
      buf[0]=0;
      buf[0]=START;
      buf[1]=ADDR;
      buf[2]=WRITE_CMD;
      >
      write(_fd, buf, 6);
      read(_fd,buf_re t,6);
      You don't even need ctypes. In C, `char` is a small integer: 'A' and the
      number 65 are interchangeable . In Python, there are no chars but strings
      of length 1, which are not the same thing as their ordinal integer.
      The easiest way is to define those constants as strings instead:

      START = chr(0x33)
      RETURN_START = chr(0x22)
      ADDR = chr(0x01)
      WRITE_CMD = chr(0x03)
      ALL_CMD = chr(0xFF)
      NUL = chr(0)

      buf = START + ADDR + WRITE_CMD + NUL + NUL + NUL
      # I assume the buffer was initialized to NULs, because only 3 bytes
      # are filled but 6 bytes are written.
      os.write(_fd, buf)
      buf_ret = os.read(_fd, 6)

      --
      Gabriel Genellina

      Comment

      • Gabriel Genellina

        #4
        Re: C to python conversion

        En Sat, 12 Apr 2008 07:58:47 -0300, Michele Petrazzo
        <michele.petraz zo@TOGLIunipex. itescribió:
        Hi all,
        I'm trying to translate a simple C code into a python + ctypes (where
        need), but I have some problems on char conversion. The code have
        to work on Linux and talk with the serial port. I think that the problem
        is that I don't translate correctly the strings.
        >
        C code:
        #define START 0x33
        #define RETURN_START 0x22
        #define ADDR 0x01
        #define WRITE_CMD 0x03
        #define ALL_CMD 0xFF
        ...
        char buf[10];
        char buf_ret[10];
        >
        buf[0]=0;
        buf[0]=START;
        buf[1]=ADDR;
        buf[2]=WRITE_CMD;
        >
        write(_fd, buf, 6);
        read(_fd,buf_re t,6);
        You don't even need ctypes. In C, `char` is a small integer: 'A' and the
        number 65 are interchangeable . In Python, there are no chars but strings
        of length 1, which are not the same thing as their ordinal integer.
        The easiest way is to define those constants as strings instead:

        START = chr(0x33)
        RETURN_START = chr(0x22)
        ADDR = chr(0x01)
        WRITE_CMD = chr(0x03)
        ALL_CMD = chr(0xFF)
        NUL = chr(0)

        buf = START + ADDR + WRITE_CMD + NUL + NUL + NUL
        # I assume the buffer was initialized to NULs, because only 3 bytes
        # are filled but 6 bytes are written.
        os.write(_fd, buf)
        buf_ret = os.read(_fd, 6)

        --
        Gabriel Genellina

        Comment

        • Ivan Illarionov

          #5
          Re: C to python conversion

          On Apr 13, 7:58 am, "Gabriel Genellina" <gagsl-...@yahoo.com.a r>
          wrote:
          En Sat, 12 Apr 2008 07:58:47 -0300, Michele Petrazzo
          <michele.petra. ..@TOGLIunipex. itescribió:
          >
          >
          >
          Hi all,
          I'm trying to translate a simple C code into a python + ctypes (where
          need), but I have some problems on char conversion. The code have
          to work on Linux and talk with the serial port. I think that the problem
          is that I don't translate correctly the strings.
          >
          C code:
          #define START 0x33
          #define RETURN_START 0x22
          #define ADDR 0x01
          #define WRITE_CMD 0x03
          #define ALL_CMD 0xFF
          ...
          char buf[10];
          char buf_ret[10];
          >
          buf[0]=0;
          buf[0]=START;
          buf[1]=ADDR;
          buf[2]=WRITE_CMD;
          >
          write(_fd, buf, 6);
          read(_fd,buf_re t,6);
          >
          You don't even need ctypes. In C, `char` is a small integer: 'A' and the
          number 65 are interchangeable . In Python, there are no chars but strings
          of length 1, which are not the same thing as their ordinal integer.
          The easiest way is to define those constants as strings instead:
          >
          START = chr(0x33)
          RETURN_START = chr(0x22)
          ADDR = chr(0x01)
          WRITE_CMD = chr(0x03)
          ALL_CMD = chr(0xFF)
          NUL = chr(0)
          >
          buf = START + ADDR + WRITE_CMD + NUL + NUL + NUL
          # I assume the buffer was initialized to NULs, because only 3 bytes
          # are filled but 6 bytes are written.
          os.write(_fd, buf)
          buf_ret = os.read(_fd, 6)
          >
          --
          Gabriel Genellina
          The easiest way is to use struct:

          START = 0x33
          RETURN_START = 0x22
          ADDR = 0x01
          WRITE_CMD = 0x03
          ALL_CMD = 0xFF

          buf = struct.pack('3b 3x', START, ADDR, WRITE_CMD)
          os.write(_fd, buf)
          buf_ret = os.read(_fd, 6)

          And, definitely, no need for ctypes here.

          --
          Ivan Illarionov

          Comment

          Working...