Skip to content

Instantly share code, notes, and snippets.

@joshbode
Created April 5, 2014 13:24
Show Gist options
  • Save joshbode/9991881 to your computer and use it in GitHub Desktop.
Save joshbode/9991881 to your computer and use it in GitHub Desktop.
Test FFI on Python
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "ffi_test.h"
const char greeting_format[] = "%s, %s, you old %s, you!";
/* get species name */
char *get_species(Species species) {
switch (species) {
case HUMAN:
return "human";
case CANINE:
return "dog";
default:
return "entity";
}
}
/* get greeting */
char *get_greeting(Greeting greeting) {
switch (greeting) {
case HELLO:
return "Hello";
case HI:
return "Hi";
case YO:
return "Yo";
default:
return "Hello";
}
}
/* generate greeting */
char *greet(const Being being) {
char *s = get_species(being.species);
char *g = get_greeting(being.greeting);
char *result = malloc(
snprintf(NULL, 0, greeting_format, g, being.name, s) + 1
);
sprintf(result, greeting_format, g, being.name, s);
return result;
}
/* generate random numbers to fill array */
void randn(int n, float *array) {
for (int i = 0; i < n; i++) {
array[i] = (float) rand() / RAND_MAX;
}
}
#ifndef FFI_TEST
#define FFI_TEST
typedef enum Species {
HUMAN, CANINE
} Species;
typedef enum Greeting {
HELLO, HI, YO
} Greeting;
typedef struct Being {
char name[1024];
Species species;
Greeting greeting;
} Being;
char *greet(const Being being);
void randn(int n, float *array);
#endif
#!/usr/bin/env python
import time
import os.path
import cffi
PATH = os.path.split(__file__)[0]
# define the API
ffi = cffi.FFI()
ffi.cdef("""
void free(void *);
void srand(unsigned seed);
typedef enum Species {
HUMAN, CANINE
} Species;
typedef enum Greeting {
HELLO, HI, YO
} Greeting;
typedef struct Being {
char name[1024];
Species species;
Greeting greeting;
} Being;
char *greet(const Being being);
void randn(int n, float *array);
""")
# load the library. performs compilation if necessary
lib = ffi.verify("""
#include <ffi_test.h>
#include <stdlib.h>
""", sources=[os.path.join(PATH, 'ffi_test.c')], include_dirs=[PATH])
# arrays
seed = int((time.time() % 1) * 1e6)
lib.srand(seed)
array = ffi.new('float[10000]')
lib.randn(10000, array)
print sum(array)
# structs
beings = ffi.new("Being[]", [
('Josh', lib.HUMAN, lib.YO),
('Ziggy', lib.CANINE, lib.HI),
])
for being in beings:
print being
salutation = ffi.gc(lib.greet(being), lib.free)
print ffi.string(salutation)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment