Calling a C program from a Python script

This process is made simple with Python’s subprocess module.

Here is the C program I want to call:

#include <stdio.h>

void CRC_calcCrc8( unsigned short int *crcReg, unsigned short int poly, unsigned char Data);

unsigned short int val=0xFFFF;
unsigned short int *reg=&val;
unsigned char data_buf[20] = {0};

int main( int argc, char *argv[] )
{

char *myString=argv[1];
int myVal;
sscanf(myString, "%x", &myVal);
int i=0;
for(i=1 ; i<argc ; i++)
{
char *myString=argv[i];
int myVal;
sscanf(myString, "%x", &myVal);
//printf("The value was read in: it is %0x in hex, or %d in decimal\n", myVal, myVal);
data_buf[i-1] = myVal;

}

for (i=0; i<(argc-1); i++) CRC_calcCrc8(&val,0x1021,data_buf[i]);
printf("%d\n",val);

return 0;
}

void CRC_calcCrc8( unsigned short int *crcReg, unsigned short int poly, unsigned char Data)
{

unsigned short int i;
unsigned short int xorFlag;
unsigned short int bit;
unsigned short int dcdBitMask = 0x80;
for(i=0; i<8; i++)
{
// Get the carry bit. This determines if the polynomial should be
// xor'd with the CRC register.
xorFlag = *crcReg & 0x8000;
// Shift the bits over by one.
*crcReg <<= 1;
// Shift in the next bit in the data byte
bit = ((Data & dcdBitMask) == dcdBitMask);
*crcReg |= bit;
// XOR the polynomial
if(xorFlag)
{
*crcReg = *crcReg ^ poly;
}
// Shift over the dcd mask
dcdBitMask >>= 1;
}
//printf("%d\n",*crcReg);
}

This CRC calculator function was provided in the datasheet of an RFID reader I am currently using. Instead of trying to replicate this in Python it is easier to just call the C program from Python and get the returned CRC value. The first for loop in the C program contains instructions to convert the arguments passed to the int main function from string to hex values. These hex values are stored in an array and passed to the CRC calculator function one by one.

Here is an example of passing arguments to the above program in the command line:
image3047

This python script replicates this using the subprocess module:

import subprocess

crc = subprocess.check_output(["./a.out", "5b", "4c", "ff", "09"])
crc= crc.replace("n", "")
print 'crc = ' , crc

Here is the output of the script:
Selection_072

2 thoughts on “Calling a C program from a Python script

  1. For fun you could also try the ctypes module. You would import ctypes and reference the .dll or .so file generated by the c compiler.
    Then you wouldn’t have to parse the output directly if (say) there was an error caused by one of your arguments.
    e.g.
    “`
    from ctypes import *
    # here accessing windows dll msvcrt which uses cdecl compilation style
    libc = cdll.msvcrt # could use cdll, windll, oledll to access your dll file depending on how compiled.
    print libc.printf
    print libc.time(None)
    print hex(windll.kernel32.GetModuleHandleA(None))
    #
    printf = libc.printf
    printf(“%d bottles of beern”, 42)
    printf(“An int %d, a double %fn”, 1234, c_double(3.14))
    printf.argtypes = [c_char_p, c_char_p, c_int, c_double]
    printf(“String ‘%s’, Int %d, Double %fn”, “Hi”, 10, 2.2)

    “`
    more detail here:
    http://python.net/crew/theller/ctypes/tutorial.html
    C and C++ hints
    http://stackoverflow.com/questions/7586504/python-accessing-dll-using-ctypes
    Cookbook for ctypes
    http://wiki.scipy.org/Cookbook/Ctypes

    super useful for more complex C programs that might not have suitable command line interfaces.

Leave a Reply

%d bloggers like this: