<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>therning.org/ magnus &#187; hsc2hs</title>
	<atom:link href="http://therning.org/magnus/archives/tag/hsc2hs/feed" rel="self" type="application/rss+xml" />
	<link>http://therning.org/magnus</link>
	<description>Incoherent mumblings</description>
	<lastBuildDate>Thu, 12 Jan 2012 13:40:30 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Haskell and C&#8212;structs</title>
		<link>http://therning.org/magnus/archives/315</link>
		<comments>http://therning.org/magnus/archives/315#comments</comments>
		<pubDate>Tue, 07 Aug 2007 08:33:51 +0000</pubDate>
		<dc:creator>Magnus</dc:creator>
				<category><![CDATA[Posts]]></category>
		<category><![CDATA[haskell]]></category>
		<category><![CDATA[hsc2hs]]></category>

		<guid isPermaLink="false">http://therning.org/magnus/archives/315</guid>
		<description><![CDATA[When creating Haskell bindings for a C library one will sooner or later have to deal with &#8216;structs&#8217;. Let&#8217;s look at how it can be done using hsc2hs. Here&#8217;s a somewhat silly struct that&#8217;ll do for this example: typedef struct { int a; int b; } Foo; It goes the file foo.h. I need some [...]]]></description>
			<content:encoded><![CDATA[<p>When creating Haskell bindings for a C library one will sooner or later have to deal with &#8216;structs&#8217;. Let&#8217;s look at how it can be done using <a href="http://haskell.org/ghc/docs/latest/html/users_guide/hsc2hs.html">hsc2hs</a>.</p>

<p>Here&#8217;s a somewhat silly struct that&#8217;ll do for this example:</p>

<pre><code>typedef struct {
    int a;
    int b;
} Foo;
</code></pre>

<p>It goes the file <em>foo.h</em>.  I need some way of making sure that the data was passed properly from Haskell to C so here&#8217;s a declaration for a function to print an instance of <code>Foo</code>:</p>

<pre><code>void print_foo(Foo *);
</code></pre>

<p>The actual implementation of <code>print_foo</code> goes into <em>foo.c</em>:</p>

<pre><code>void
print_foo(Foo *f)
{
    printf("%s\n", __FUNCTION__);
    printf("f-&gt;a: %i\n", f-&gt;a);
    printf("f-&gt;b: %i\n", f-&gt;b);
}
</code></pre>

<p>No surprises so far.  Now onto the Haskell side of things.  First some basic setup:</p>

<pre><code>{-# OPTIONS -ffi #-}
module Main
    where

import Foreign
import Foreign.C.Types
</code></pre>

<p>That makes sure I don&#8217;t forget to tell GHC that I&#8217;m using the foreign function interface (FFI) and imports everything I need for the rest.  <em>hsc2hs</em> needs to know about the struct so I simply include the header file.  I also need the Haskell representation of <code>Foo</code>, called <code>Bar</code> here, and for convenience I add a type for a pointer to <code>Bar</code>:</p>

<pre><code>#include "foo.h"

data Bar = Bar { a :: Int, b :: Int }
type BarPtr = Ptr (Bar)
</code></pre>

<p>Now I&#8217;m ready to add the declaration of the &#8220;foreign&#8221; function:</p>

<pre><code>foreign import ccall "static foo.h print_foo"
    f_print_foo :: BarPtr -&gt; IO ()
</code></pre>

<p>Looking through the standard modules it isn&#8217;t completely obvious how to create a <code>BarPtr</code> for passing to <code>f_print_foo</code>.  Whit the help of people on <code>#haskell</code> I found <code>with</code>, which has the type <em>Storable a => a -> (Ptr a -> IO b) -> IO b</em>.  That means I have to make <code>Bar</code> a <code>Storable</code>.  According to the <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Foreign-Storable.html#t%3AStorable">documentation on Storable</a> and some experimentation I found that for this particular example I only need full implementations of <code>sizeOf</code>, <code>alignment</code> and <code>poke</code>:</p>

<pre><code>instance Storable Bar where
    sizeOf _ = (#size Foo)
    alignment _ = alignment (undefined :: CInt)
    peek _ = error "peek is not implemented"
    poke ptr (Bar a' b') = do
        (#poke Foo, a) ptr a'
        (#poke Foo, b) ptr b'
</code></pre>

<p>([<em>Edited 09-08--2007 07:43 BST</em>] See DeeJay&#8217;s comment below for an explanation of the definition of <code>alignment</code>.)</p>

<p>Using <code>with</code> every time I have to call <code>f_print_foo</code> will get tiring so here&#8217;s a function that&#8217;s a bit more convenient to use:</p>

<pre><code>printFoo b = with b f_print_foo
</code></pre>

<p>Now I can write a small main function to test it all:</p>

<pre><code>main = printFoo $ Bar { a=17, b=47 }
</code></pre>

<p>It works beautifully.  However it&#8217;s very limited since it only covers the cases when a C function takes a pointer to a struct as a pure <em>in</em> argument.  What about <em>inout</em>?  (It&#8217;ll be easy to see how to deal with <em>out</em> arguments once the <em>inout</em> case is covered.)  So, here&#8217;s a C function that adds 1 to one of the members in the struct:</p>

<pre><code>void
add_a(Foo *f)
{
    printf("%s\n", __FUNCTION__);
    f-&gt;a++;
}
</code></pre>

<p>Of course a declaration in the header file is needed as well, but that&#8217;s pretty obvious so I&#8217;ll skip it here.  The declaration of the foreign function is as simple as for <code>f_print_foo</code>:</p>

<pre><code>foreign import ccall "static foo.h add_a"
    f_add_a :: BarPtr -&gt; IO ()
</code></pre>

<p>Now comes the interesting part.  Writing a convenience function for <code>f_add_a</code> isn&#8217;t as straight forward as for <code>f_print_foo</code>.  I think something with the type <em>Bar -> IO Bar</em> would be useful.  <code>with</code> creates a temporary <code>BarPtr</code> for the duration of the call which means I have to have an inner function that takes the <code>Bar</code> part out of the <code>BarPtr</code> and returns it inside IO.  Luckily <code>peek</code> does exactly that.  Adding an implementation of it means that <code>Bar</code> as a <code>Storable</code> is implemented like this:</p>

<pre><code>instance Storable Bar where
    sizeOf _ = (#size Foo)
    alignment _ = 1 -- ???
    peek ptr = do
        a' &lt;- (#peek Foo, a) ptr
        b' &lt;- (#peek Foo, b) ptr
        return Bar { a=a', b=b' }
    poke ptr (Bar a' b') = do
        (#poke Foo, a) ptr a'
        (#poke Foo, b) ptr b'
</code></pre>

<p>And the convenience function for <code>f_add_a</code> can be written like this:</p>

<pre><code>addA b = with b $ \ p -&gt; f_add_a p &gt;&gt; peek p
</code></pre>

<p>Then I can modify the main function to test this as well:</p>

<pre><code>main = do
    b &lt;- return $ Bar { a=17, b=47 }
    printFoo b
    d &lt;- addA b
    printFoo b
    printFoo d
</code></pre>

<p>Indeed, produces the expected out put:</p>

<pre><code>print_foo
f-&gt;a: 17
f-&gt;b: 47
add_a
print_foo
f-&gt;a: 17
f-&gt;b: 47
print_foo
f-&gt;a: 18
f-&gt;b: 47
</code></pre>

<p>Pure <em>out</em> arguments can be handled using <code>alloca</code> with a function similar to the one I pass to <code>with</code> in <code>addA</code> above.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Ftherning.org%2Fmagnus%2Farchives%2F315&amp;title=Haskell%20and%20C%26%238212%3Bstructs" id="wpa2a_2">Share/Bookmark</a></p>]]></content:encoded>
			<wfw:commentRss>http://therning.org/magnus/archives/315/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
	</channel>
</rss>

