From: John Whitington <john@coherentgraphics.co.uk>
To: David MENTRE <dmentre@linux-france.org>
Cc: caml-list@inria.fr
Subject: Re: [Caml-list] Coherent Graphics Product Updates
Date: Thu, 12 Jul 2012 17:27:59 +0100 [thread overview]
Message-ID: <4FFEFB0F.5080506@coherentgraphics.co.uk> (raw)
In-Reply-To: <CAC3Lx=Yjj83wDicWjBGBeMbwJS3CsHCfgi4Ttj1FkZjnLCj0rQ@mail.gmail.com>
Hi,
David MENTRE wrote:
> Hello,
>
> 2012/7/12 John Whitington<john@coherentgraphics.co.uk>:
>> 1. A new version of our PDF editor for OS X (PDF manipulation in OCaml,
>> interface in Objective C):
>
> An architectural question: how your backend OCaml part and your
> Objective C GUI are communicating between each other?
It's entirely one-way. Objective C calls OCaml. OCaml never calls
Objective C.
Here's the makefile for the library - this method is straight out of the
OCaml manual.
mklib:
ocamlc.opt cpdfstrftime.mli;
ocamlopt.opt -c -I . unix.cmxa str.cmxa bigarray.cmxa cgutil.cmxa
camlpdf.cmxa cpdfstrftime.ml;
ocamlc.opt cpdf.mli;
ocamlopt.opt -c -I . unix.cmxa str.cmxa bigarray.cmxa cgutil.cmxa
camlpdf.cmxa cpdf.ml;
ocamlc.opt cpdflib.mli;
ocamlopt.opt -c -I . unix.cmxa str.cmxa bigarray.cmxa cgutil.cmxa
camlpdf.cmxa cpdf.cmx cpdflib.ml;
ocamlc.opt cpdflibwrapper.c;
ocamlopt.opt -output-obj -o cpdflib.o unix.cmxa bigarray.cmxa
cgutil.cmxa camlpdf.cmxa cpdfstrftime.cmx cpdf.cmx cpdflib.cmx;
cp /usr/local/lib/ocaml/libasmrun.a cpdflib.a;
ar r cpdflib.a cpdflib.o cpdflibwrapper.o
test: zlibstubs.o cpdflib.a cpdflibc-test.c
cc -c cpdflibc-test.c -o cpdflibc-test.o; \
cc -L'/usr/local/lib/ocaml' -lunix -lbigarray -lz -o test
cpdflibc-test.o zlibstubs.o cpdflib.a
For example, for a single function 'fromFile' to load a PDF from disc:
cpdflib.ml (Wraps up functionality from our command line tools imperatively)
==============================================================
(* Read a file, no attempt at decryption, unless it's the blank user
password. *)
let fromFile filename =
try
new_pdf (Pdfread.pdf_of_file (Some "") None filename)
with
e -> handle_error "fromFile" e; err_int
let _ = Callback.register "fromFile" fromFile
cpdflibwrapper.c (the foreign function interface)
=================================================
int fromFile(char* filename)
{
CAMLparam0 ();
CAMLlocal3(fromfile_v, filename_v, result_v);
fromfile_v = *caml_named_value("fromFile");
filename_v = caml_copy_string(filename);
result_v = caml_callback(fromfile_v, filename_v);
updateLastError ();
CAMLreturnT(int, Int_val(result_v));
}
PDFDocument.m (Objective C)
===========================
...
clearError ();
const char* in_c = [[[self fileURL] path] UTF8String];
int pdf = fromFile((char*) in_c);
if (lastError != 0) return NO;
...
Functions like handle_error, updateLastError(), clearError() etc.
provide a simple flat system for dealing with errors without exceptions
crossing the C/OCaml boundary. This is very old fashioned, but seems to
work. C code checks the error code after each callback to Ocaml, and can
extract extra information about the error.
Similarly, no complicated OCaml data structures cross the boundary -
it's all direct ints, floats, strings, and the occasional void*. The
possibility for programmer error in building big OCaml data structures
directly in C seems to outweigh the annoyance of a slightly flat
interface, at least for this particular application. FFI Masters may
disagree :-)
The multiple PDF files representing different undo/redo states of a
document are held in memory in OCaml (with most of the data shared
between them automatically, of course). When the PDF is updated or
undone/redone, it's flattened to disk, and the PDFKit component in Cocoa
picks it up and renders it - surprisingly, this is quick enough - it's
all in the memory cache rather than the actual disk usually, of course.
PDFKit (The cocoa PDF component) is only used for rendering - almost
every other piece of functionality is dealt with by CamlPDF via the FFI.
Thanks,
--
John Whitington
Director, Coherent Graphics Ltd
http://www.coherentpdf.com/
next prev parent reply other threads:[~2012-07-12 16:28 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-07-12 13:04 John Whitington
2012-07-12 15:51 ` David MENTRE
2012-07-12 16:27 ` John Whitington [this message]
2012-07-12 16:44 ` David MENTRE
2012-07-13 0:27 ` Francois Berenger
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4FFEFB0F.5080506@coherentgraphics.co.uk \
--to=john@coherentgraphics.co.uk \
--cc=caml-list@inria.fr \
--cc=dmentre@linux-france.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox