From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@sympa.inria.fr Delivered-To: caml-list@sympa.inria.fr Received: from mail2-relais-roc.national.inria.fr (mail2-relais-roc.national.inria.fr [192.134.164.83]) by sympa.inria.fr (Postfix) with ESMTPS id 3CDBB7EE25 for ; Fri, 7 Jun 2013 01:17:48 +0200 (CEST) Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of yallop@gmail.com) identity=pra; client-ip=74.125.82.181; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="yallop@gmail.com"; x-sender="yallop@gmail.com"; x-conformance=sidf_compatible Received-SPF: Pass (mail2-smtp-roc.national.inria.fr: domain of yallop@gmail.com designates 74.125.82.181 as permitted sender) identity=mailfrom; client-ip=74.125.82.181; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="yallop@gmail.com"; x-sender="yallop@gmail.com"; x-conformance=sidf_compatible; x-record-type="v=spf1" Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of postmaster@mail-we0-f181.google.com) identity=helo; client-ip=74.125.82.181; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="yallop@gmail.com"; x-sender="postmaster@mail-we0-f181.google.com"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Au0AAJQXsVFKfVK1k2dsb2JhbABZgzmDPLwmCBYOAQEBAQcLCwkUBCSCTQQZARseAxIQDwImAiQBEQEFASKIDQEDDwybAoJ+i3tPgn+EVwoZJw1Yh3QBBQyBGpBagRQDlz+BKY4yFimENjs X-IPAS-Result: Au0AAJQXsVFKfVK1k2dsb2JhbABZgzmDPLwmCBYOAQEBAQcLCwkUBCSCTQQZARseAxIQDwImAiQBEQEFASKIDQEDDwybAoJ+i3tPgn+EVwoZJw1Yh3QBBQyBGpBagRQDlz+BKY4yFimENjs X-IronPort-AV: E=Sophos;i="4.87,818,1363129200"; d="scan'208";a="20757287" Received: from mail-we0-f181.google.com ([74.125.82.181]) by mail2-smtp-roc.national.inria.fr with ESMTP/TLS/RC4-SHA; 07 Jun 2013 01:17:47 +0200 Received: by mail-we0-f181.google.com with SMTP id p58so2528640wes.40 for ; Thu, 06 Jun 2013 16:17:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:date:message-id:subject:from:to:content-type; bh=tSIPFKGFWSfuwrVD6ZVbuzzkd63/aCm0Vn/ApTJTYMI=; b=rCpqsAzxu8u+OTmm+p7AkZY/LktUxslQEewKYITShc0XMq/8GFf5HCGeYH6VhasOAh 3WThPxge0/Abo4hWOagQBASu07TY41ex9YsXbilI1WWKyitEI/w+pdqxpvEQ8LDk+5DA m6aBC3ocTkdEMroi22T9W8yf1CB1FJRRQYD18fKD8oBreLL7IoXYB2HFz2mFsJjeGwtD xfVM/DGUEusGeMh8Y9dQbwpQc7EkagpBZjggDG3NNJ8BORsKztc+6x9LDu4ERplqJoN2 n7hgvLx/nZ/3hMkKmJFBk8WSOny6+sFBdXfx5qlAj0CxFt/kEoU1xuV0RONwG2Hz1+uc EjQA== MIME-Version: 1.0 X-Received: by 10.194.9.101 with SMTP id y5mr2485928wja.86.1370560667423; Thu, 06 Jun 2013 16:17:47 -0700 (PDT) Received: by 10.216.93.9 with HTTP; Thu, 6 Jun 2013 16:17:47 -0700 (PDT) Date: Fri, 7 Jun 2013 00:17:47 +0100 Message-ID: From: Jeremy Yallop To: Caml List Content-Type: text/plain; charset=UTF-8 Subject: [Caml-list] ANN: ocaml-ctypes, a library for calling C functions directly from OCaml I'm happy to announce the initial release of ocaml-ctypes. The ocaml-ctypes library makes it possible to call C functions directly from OCaml without writing or generating C code. The core of the library is a set of combinators for describing C types -- scalars, functions, structs, unions, arrays, and pointers to values and functions. Type descriptions can then be used to bind native functions and values. Here's a simple example: # let puts = foreign "puts" (string @-> returning int);; val puts : string -> int = # puts "Hello, world!";; Hello, world! Here's a more substantial example that shows how to describe a C structure type, map the type to an OCaml record, and call a function that returns the structure. (* Describe the C struct. There are two fields, both ints. *) let div_t = structure "div_t";; let q = div_t *:* int let r = div_t *:* int let () = seal div_t (* Define the OCaml record that we'll use to view the C structure. *) type div_result = { quot : int; rem: int } (* Define the conversions between the C struct and the OCaml record. *) let div_result_of_div_t d = { quot = getf d q; rem = getf d r } let div_t_of_div_result {quot; rem} = let d = make div_t in (setf d q quot; setf d r rem; d) (* Create a "view type" for that looks like div_result and behaves like div_t *) let div_result = view ~read:div_result_of_div_t ~write:div_t_of_div_result div_t (* Bind to the standard C `div' function *) let div = foreign "div" (int @-> int @-> returning div_result) (* Try it out *) # div 17 2;; - : div_result = {quot = 8; rem = 1} The distribution contains larger examples and a fairly extensive test suite, showing how to use other features of the library, such as binding to functions that accept callback arguments. Among the examples is Anil Madhavapeddy's port of the `curses' example from the OCaml documentation; it's instructive to compare the two implementations: OCaml manual curses example http://caml.inria.fr/pub/docs/manual-ocaml/manual033.html#toc147 ocaml-ctypes curses example https://github.com/ocamllabs/ocaml-ctypes/blob/master/examples/ncurses/ncurses.ml Detailed installation instructions for ocaml-ctypes can be found in the tutorial. (Briefly: ensure libffi is installed, then 'opam install ctypes'.) Comments, bug reports, and other feedback are most welcome. Tutorial: https://github.com/ocamllabs/ocaml-ctypes/wiki/ctypes-tutorial Examples: https://github.com/ocamllabs/ocaml-ctypes/tree/master/examples API documentation: http://ocamllabs.github.io/ocaml-ctypes/ Github repository: https://github.com/ocamllabs/ocaml-ctypes Direct download: https://github.com/ocamllabs/ocaml-ctypes/archive/ocaml-ctypes-0.1.tar.gz