caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* linking errors involving cpp files
@ 2009-12-15  5:09 Aaron Bohannon
  2009-12-15  6:59 ` [Caml-list] " Robert Roessler
  0 siblings, 1 reply; 7+ messages in thread
From: Aaron Bohannon @ 2009-12-15  5:09 UTC (permalink / raw)
  To: OCaml List

Hi,

How do I link C++ code with OCaml?  Let's say I have a main program in
C/C++ and a function I want to call in OCaml:

---- main.c / main.cpp ---
#include <caml/mlvalues.h>
#include <caml/memory.h>
#include <caml/callback.h>
int main (int argc, char ** argv) {
  char * caml_argv[argc + 1];
  int i;
  for (i = 0; i < argc + 1; i++) caml_argv[i] = argv[i];
  caml_argv[argc] = NULL;
  caml_main (caml_argv);
  return 0;
}
--------

---- test.ml ----
let f x = x + 1
let () = Callback.register "test" f
--------

If I name the main program "main.c", I can compile the code like this
with no trouble whatsoever:

gcc -I /opt/local/lib/ocaml -c main.c
ocamlopt -o main test.cmx main.o

If I name the main program "main.cpp", and run the same commands---

gcc -I /opt/local/lib/ocaml -c main.cpp
ocamlopt -o main test.cmx main.o

---then I get this:

Undefined symbols:
  "_caml_atom_table", referenced from:
      _intern_alloc in libasmrun.a(intern.o)
      _intern_rec in libasmrun.a(intern.o)
      _caml_alloc in libasmrun.a(alloc.o)
      _caml_alloc_dummy_float in libasmrun.a(alloc.o)
      _caml_alloc_dummy in libasmrun.a(alloc.o)
      _caml_alloc_array in libasmrun.a(alloc.o)
  "___gxx_personality_v0", referenced from:
      _main in main.o
      CIE in main.o
  "_caml_code_area_start", referenced from:
      _extern_rec in libasmrun.a(extern.o)
      _extern_rec in libasmrun.a(extern.o)
      _segv_handler in libasmrun.a(signals_asm.o)
      _caml_code_checksum in libasmrun.a(intern.o)
      _intern_rec in libasmrun.a(intern.o)
  "_caml_code_area_end", referenced from:
      _extern_rec in libasmrun.a(extern.o)
      _segv_handler in libasmrun.a(signals_asm.o)
      _caml_code_checksum in libasmrun.a(intern.o)
  "caml_main(char**)", referenced from:
      _main in main.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
File "caml_startup", line 1, characters 0-1:
Error: Error during linking


Now I know gcc does something slightly different with cpp files, and I
can eliminate the complaint about the __gxx symbol if I add "-cclib
-lstdc++" (which I fully expected to need working with C++ programs).
But why are the caml symbols missing!?!?  (It took me over 2 hours to
figure out it was the "cpp" extension that was the root of these
missing caml symbols in my real program because that was the *last*
thing I expected.)  I'm using OCaml 3.11.1 on OS X 10.6.2.

- Aaron


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Caml-list] linking errors involving cpp files
  2009-12-15  5:09 linking errors involving cpp files Aaron Bohannon
@ 2009-12-15  6:59 ` Robert Roessler
  2009-12-15 13:50   ` Aaron Bohannon
  0 siblings, 1 reply; 7+ messages in thread
From: Robert Roessler @ 2009-12-15  6:59 UTC (permalink / raw)
  To: Aaron Bohannon; +Cc: OCaml List

Aaron Bohannon wrote:
> How do I link C++ code with OCaml?  Let's say I have a main program in
> C/C++ and a function I want to call in OCaml:
>
> ---- main.c / main.cpp ---
> #include<caml/mlvalues.h>
> #include<caml/memory.h>
> #include<caml/callback.h>
> int main (int argc, char ** argv) {
>    char * caml_argv[argc + 1];
>    int i;
>    for (i = 0; i<  argc + 1; i++) caml_argv[i] = argv[i];
>    caml_argv[argc] = NULL;
>    caml_main (caml_argv);
>    return 0;
> }
> --------
>...
> ---then I get this:
>
> Undefined symbols:

You might try (when mixing C++ and OCaml) wrapping the whole thing in an 
'extern "C" {...}' block (*including* the #includes and the entire main 
function).

Robert Roessler


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Caml-list] linking errors involving cpp files
  2009-12-15  6:59 ` [Caml-list] " Robert Roessler
@ 2009-12-15 13:50   ` Aaron Bohannon
  2009-12-15 13:59     ` Mark Shinwell
  2009-12-15 14:50     ` Jan Kybic
  0 siblings, 2 replies; 7+ messages in thread
From: Aaron Bohannon @ 2009-12-15 13:50 UTC (permalink / raw)
  To: Robert Roessler; +Cc: OCaml List

On Tue, Dec 15, 2009 at 1:59 AM, Robert Roessler <roessler@rftp.com> wrote:
> Aaron Bohannon wrote:
>>
>> How do I link C++ code with OCaml?

> You might try (when mixing C++ and OCaml) wrapping the whole thing in an
> 'extern "C" {...}' block (*including* the #includes and the entire main
> function).

Thanks for the tip.  This does resolve the missing caml symbols (even
when naming the file with a cpp extension).  However, my real program
actually uses some C++ features.  I think I could convert it to a real
C program, but I assumed there would be some other way.

 - Aaron


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Caml-list] linking errors involving cpp files
  2009-12-15 13:50   ` Aaron Bohannon
@ 2009-12-15 13:59     ` Mark Shinwell
  2009-12-15 20:47       ` Aaron Bohannon
  2009-12-15 14:50     ` Jan Kybic
  1 sibling, 1 reply; 7+ messages in thread
From: Mark Shinwell @ 2009-12-15 13:59 UTC (permalink / raw)
  To: Aaron Bohannon; +Cc: caml-list

On Tue, Dec 15, 2009 at 08:50:33AM -0500, Aaron Bohannon wrote:
> On Tue, Dec 15, 2009 at 1:59 AM, Robert Roessler <roessler@rftp.com> wrote:
> > Aaron Bohannon wrote:
> >>
> >> How do I link C++ code with OCaml?
> 
> > You might try (when mixing C++ and OCaml) wrapping the whole thing in an
> > 'extern "C" {...}' block (*including* the #includes and the entire main
> > function).
> 
> Thanks for the tip.  This does resolve the missing caml symbols (even
> when naming the file with a cpp extension).  However, my real program
> actually uses some C++ features.  I think I could convert it to a real
> C program, but I assumed there would be some other way.

I suspect it will work if only the #include directives pertaining to Caml
header files are marked as 'extern "C"'.  You just need to tell the compiler to
use the C linkage convention rather than the C++ name mangling convention for
the external Caml functions that your program (implicitly or explicitly) calls.
This is done at the function prototype site, not the call site.  Everything
else in the program should be unaffected.

Xavier, could the headers have the guards added?  (I only spot-checked one,
mlvalues.h, and that didn't appear to have it).

Mark


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Caml-list] linking errors involving cpp files
  2009-12-15 13:50   ` Aaron Bohannon
  2009-12-15 13:59     ` Mark Shinwell
@ 2009-12-15 14:50     ` Jan Kybic
  2009-12-15 15:04       ` Basile STARYNKEVITCH
  1 sibling, 1 reply; 7+ messages in thread
From: Jan Kybic @ 2009-12-15 14:50 UTC (permalink / raw)
  To: Aaron Bohannon; +Cc: OCaml List

On Tue, Dec 15, 2009 at 2:50 PM, Aaron Bohannon <bohannon@cis.upenn.edu> wrote:
>
> Thanks for the tip.  This does resolve the missing caml symbols (even
> when naming the file with a cpp extension).  However, my real program
> actually uses some C++ features.  I think I could convert it to a real
> C program, but I assumed there would be some other way.
>

What you can do is to create a thin C layer between your Ocaml and C++ code.
I am including a very simple code - an interface to the Cubpack
library in Ocaml.

If your interface is big, you might try some of the authomatic
builders like SWIG (http://www.swig.org) which I understand can wrap
C++ classes for use in Ocaml.

Jan

-- 
-------------------------------------------------------------------------
Jan Kybic <kybic@fel.cvut.cz>                       tel. +420 2 2435 5721
http://cmp.felk.cvut.cz/~kybic                      ICQ 20056945

// stub to call Cubpack++ integration routines from Ocaml
//
//
// Jan Kybic, February 2004
// $Id: cubpack_stub.cc 322 2004-02-06 18:03:01Z jkybic $

extern "C" {
#include <caml/mlvalues.h>
#include <caml/memory.h>
#include <caml/alloc.h>
#include <caml/callback.h>
}

#include <cubpack.h>
#include <stdio.h>

// This code is NOT thread safe
// There is nothing to do about it except change Cubpack++

static value ocamlCallback ;

// Call a Ocaml function with two arguments u,v
real evalOcaml(const Point& p) {
  CAMLparam0() ;
  double z ;
  CAMLlocal3(ou,ov,oz) ;
  ou=copy_double(p.X()) ;
  ov=copy_double(p.Y()) ;
  oz=callback2(ocamlCallback,ou,ov) ;
  z=Double_val(oz) ;
  CAMLreturn(z) ;
}

static double doIntegrate(double a, double r,int m) {
  CAMLparam0() ;
  Point p1(0.0,0.0), p2(0.0,1.0), p3(1.0,0.0);
  TRIANGLE T(p1,p2,p3);
  CAMLreturn (Integrate(evalOcaml,T)) ;
}

extern "C"
// parameters: absolute and relative error bounds, maximum number
// of evaluations, the function to evaluate
value cubpackIntegrateTriangle (value a,value r,value m,value f) {
  CAMLparam4(a,r,m,f) ; // register for GC
  CAMLlocal1(z) ;
  register_global_root(&ocamlCallback) ;
  ocamlCallback=f ;
  z=copy_double(doIntegrate(Double_val(a),Double_val(r),Int_val(m))) ;
  remove_global_root(&ocamlCallback) ;
  CAMLreturn(z) ;
}


// end of cubpack_stub.cc


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Caml-list] linking errors involving cpp files
  2009-12-15 14:50     ` Jan Kybic
@ 2009-12-15 15:04       ` Basile STARYNKEVITCH
  0 siblings, 0 replies; 7+ messages in thread
From: Basile STARYNKEVITCH @ 2009-12-15 15:04 UTC (permalink / raw)
  To: kybic; +Cc: Aaron Bohannon, OCaml List

Jan Kybic wrote:
> On Tue, Dec 15, 2009 at 2:50 PM, Aaron Bohannon <bohannon@cis.upenn.edu> wrote:
>> Thanks for the tip.  This does resolve the missing caml symbols (even
>> when naming the file with a cpp extension).  However, my real program
>> actually uses some C++ features.  I think I could convert it to a real
>> C program, but I assumed there would be some other way.
>>
> 
> What you can do is to create a thin C layer between your Ocaml and C++ code.
> I am including a very simple code - an interface to the Cubpack
> library in Ocaml.
> 


In addition of all the other good answers, you could look at how some existing C++ open-source libraries interface to Ocaml.

Both the Parma Polyhedra Library (PPL, under GPLv3 licence), at http://www.cs.unipr.it/ppl/ and the Low Level Virtual 
Machine library (LLVM, under a BSD-like licence) at http://llvm.org/ are free libraries, coded in C++, interfaced to Ocaml.

Regards.


-- 
Basile STARYNKEVITCH         http://starynkevitch.net/Basile/
email: basile<at>starynkevitch<dot>net mobile: +33 6 8501 2359
8, rue de la Faiencerie, 92340 Bourg La Reine, France
*** opinions {are only mines, sont seulement les miennes} ***


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Caml-list] linking errors involving cpp files
  2009-12-15 13:59     ` Mark Shinwell
@ 2009-12-15 20:47       ` Aaron Bohannon
  0 siblings, 0 replies; 7+ messages in thread
From: Aaron Bohannon @ 2009-12-15 20:47 UTC (permalink / raw)
  To: Mark Shinwell; +Cc: caml-list

Yes, it seems you're right.  I just need the "extern" annotation
around the includes.

extern "C" {
#include <caml/mlvalues.h>
#include <caml/memory.h>
#include <caml/callback.h>
}

Thanks to everyone for the helpful comments.

 - Aaron

On Tue, Dec 15, 2009 at 8:59 AM, Mark Shinwell <mshinwell@janestreet.com> wrote:
> On Tue, Dec 15, 2009 at 08:50:33AM -0500, Aaron Bohannon wrote:
>> On Tue, Dec 15, 2009 at 1:59 AM, Robert Roessler <roessler@rftp.com> wrote:
>> > Aaron Bohannon wrote:
>> >>
>> >> How do I link C++ code with OCaml?
>>
>> > You might try (when mixing C++ and OCaml) wrapping the whole thing in an
>> > 'extern "C" {...}' block (*including* the #includes and the entire main
>> > function).
>>
>> Thanks for the tip.  This does resolve the missing caml symbols (even
>> when naming the file with a cpp extension).  However, my real program
>> actually uses some C++ features.  I think I could convert it to a real
>> C program, but I assumed there would be some other way.
>
> I suspect it will work if only the #include directives pertaining to Caml
> header files are marked as 'extern "C"'.  You just need to tell the compiler to
> use the C linkage convention rather than the C++ name mangling convention for
> the external Caml functions that your program (implicitly or explicitly) calls.
> This is done at the function prototype site, not the call site.  Everything
> else in the program should be unaffected.
>
> Xavier, could the headers have the guards added?  (I only spot-checked one,
> mlvalues.h, and that didn't appear to have it).
>
> Mark
>


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2009-12-15 20:47 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-12-15  5:09 linking errors involving cpp files Aaron Bohannon
2009-12-15  6:59 ` [Caml-list] " Robert Roessler
2009-12-15 13:50   ` Aaron Bohannon
2009-12-15 13:59     ` Mark Shinwell
2009-12-15 20:47       ` Aaron Bohannon
2009-12-15 14:50     ` Jan Kybic
2009-12-15 15:04       ` Basile STARYNKEVITCH

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).