xclerc / ocamljava

http://www.ocamljava.org
Other
170 stars 14 forks source link

Failing to add C stubs with ocamljava #29

Open PioBeat opened 5 years ago

PioBeat commented 5 years ago

OCaml allows to interface libraries written in C, for example. Therefore, C stubs must be added to use the C library. My question is, how can I produce a *.jar from OCaml source that has a reference to C stubs?

Consider the following library ocaml-minisat. This library is a binding to the Minisat-C-1.14.1 solver. The signature of the ocaml-minisat dependency is as follows:

module Raw : sig
  external create : unit -> t = "caml_minisat_new"
  external delete : t -> unit = "caml_minisat_delete"
  (* code omitted *)
end

The C stubs are located in the same directory with the filename libminisat_stubs.c.

Running ocamljava -c Minisat.mli works fine (the interface). After calling ocamljava -c Minisat.ml the following error is produced:

File "Minisat.ml", line 1:
Error: Primitive 'caml_minisat_new' cannot be found

Is there any way to tell ocamljava where the defined C stubs of the library are located?

xclerc commented 5 years ago

I am afraid ocamljava does not support this, at least out-of-the-box. Basically, ocamljava uses the Java language where ocamlc and ocamlopt use the C language.

In other words, ocamljava expects primitives to be written in Java (to be more precise: to be compiled to static methods in .class files).

Now, there are tools in the Java world to call C functions (for instance JNA), so one could very well write an ocamljava-compatible primitive in Java that basically calls a C function.

Of course, another possibility would be to compile ocaml-minisat using ocamljava (provided it is pure OCaml - including its dependencies), but that might very well raise performance issues...

PioBeat commented 5 years ago

Thank you very much for your detailed answer.

Unfortunately, MiniSat-ocaml is not written in pure OCaml and calls C functions (I was referring to the wrong minisat library, this is the correct one MiniSat-ocaml). The issue I am facing is that I want to transform a bigger OCaml library into the Java programming language. And this "bigger" library uses the MiniSat-ocaml library. You are right; performance would be probably bad.

However, according to your JNA suggestion, it is possible to do it from the Java-side. But it is unclear to me, how or in which way I could change the corresponding OCaml construct to be translated correctly. It came into my mind to replace the "guilty" OCaml methods (these with the external statements) with empty code stubs. Then, ocamljava could do its transformation, and later I could add the needed bindings in Java with JNA. Would this be a possible solution? Nevertheless, I appreciate your effort and time you put into ocamljava. Very useful tool.