One of the strong points of ooc is the descriptive way C libraries can be interfaced with. These interfaces can be as low-level as a list of extern functions or 'high-level' by wrapping function calls and data within ooc classes or complex covers.
Building an interfaceEdit
In the discussion that follows we are going to build up a basic interface to the libYAML (http://pyyaml.org/wiki/LibYAML) library. There is an existing interface by nddrylliog here which we will use as a reference too.
Most of our work will involve reading the library header file (http://svn.pyyaml.org/libyaml/branches/stable/include/yaml.h) and deciding how we intend to use the contents therein. To interface with the C library we will need it to be present on our system. We will also want to create a file hierarchy for our new interface.
In this section we will make the C library accessible to our new ooc interface and create the file hierarchy for that interface.
Installing (making available) the C library is system dependent. The following steps will work for users of Ubuntu:
sudo apt-get install libyaml-dev
Another option (that is really beyond the scope of this book) is to keep libraries within a user account and control the paths where the C compiler searches for libraries and headers. An example setup that uses ~/local as a prefix could be:
mkdir ~/local cd ~/local wget http://pyyaml.org/download/libyaml/yaml-0.1.4.tar.gz tar -xzvf yaml-0.1.4.tar.gz cd yaml-0.1.4 ./configure --prefix=[absolute path to ~/local] make make install
To make use of this kind of setup you will need to set the relevant environment variables in the relevant user rc file:
export PATH=$HOME/local/bin:$PATH export LIBRARY_PATH=$HOME/local/lib:$LD_LIBRARY_PATH export LD_LIBRARY_PATH=$HOME/local/lib:$LD_LIBRARY_PATH export C_INCLUDE_PATH=$HOME/local/include:$C_INCLUDE_PATH
To make use of libraries in ooc the convention is to set the environment variable OOC_LIBS. Inkeeping with the local setup discussed above this can be a path accessible only to this user:
Since we are building an ooc library ourselves the file hierarchy belongs inside OOC_LIBS. More details on the structure of a library and the associated use file are available in the ooc documentation. For our purposes we will have something like :
ooc-yaml yaml.use source YAML.ooc samples 01-test.occ
The first step is to create a use file that describes how our ooc library is laid out and what setting it needs to compile to ooc programs that want to use it. A basic setup is the following :
Name: libYAML Version: 0.1.4 Description: Interface to libYAML Includes: yaml.h SourcePath: source
For the purposes of this discussion we are going to do all of the interface creation inside source/YAML.ooc in our file hierarchy above. Because we want this file to include the settings we established above we include the line
at the top of this file.
Wonder of wonders libYAML does not seem to define any constants! But just-in-case the library you are interfacing with does include constants your interfaces should look something like this (C code above in bold, ooc below):
#define A_FLOATING_POINT_CONSTANT 12.0 OOC_NAME_FOR_FLOATING_POINT_CONSTANT: extern( A_FLOATING_POINT_CONSTANT ) Float
#define A_STRING_CONSTANT "Twelve" OOC_NAME_FOR_STRING_CONSTANT: extern( A_STRING_CONSTANT ) CString
Interfacing with C header means coming into contact with many of the quirky parts of the C pre-processor and the tricks developers use to cross platforms and programming paradigms. libYAML uses the macro YAML_DECLARE to provide interoperability with WIN32. For our purposes we will simply expand:
#define YAML_DECLARE(type) type which makes the following declarations equivalent:
YAML_DECLARE(const char *) yaml_get_version_string(void);
const char * yaml_get_version_string(void); YAMLGetVersionString: extern( yaml_get_version_string ) func() -> CString