Created
April 5, 2014 13:24
-
-
Save joshbode/9991881 to your computer and use it in GitHub Desktop.
Test FFI on Python
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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