diff --git a/examples/CC/class.c b/examples/CC/class.c index d8c9347..fc575b7 100644 --- a/examples/CC/class.c +++ b/examples/CC/class.c @@ -6,13 +6,13 @@ Scheme primitives. See constructor.c in this directory for compilation instructions. -Here is a transcript showing a test run under Solaris 2.4 using the +Here is a transcript showing a test run under Linux using the GNU g++ compiler: - % g++ -fpic -I/usr/elk/include -c class.c + % g++ -shared -fPIC -I/usr/elk/include -c class.c -o class.so % % scheme - > (load 'class.o) + > (load 'class.so) > (define x (make-foo)) x @@ -23,7 +23,7 @@ GNU g++ compiler: > (read-val x) 11 > (exit) - % + % -----------------------------------------------------------------------------*/ @@ -72,18 +72,20 @@ Object P_Write_Val(Object x, Object y) { return Void; } -Foo_Print(Object h, Object port, int raw, int depth, int length) { +int Foo_Print(Object h, Object port, int raw, int depth, int length) { Printf(port, "#[foo %d]", FOO(h)->foo.read_val()); + return 0; } int Foo_Equal(Object x, Object y) { return FOO(x)->foo.read_val() == FOO(y)->foo.read_val(); } -void elk_init_foo() { +extern "C" void elk_init_foo() { T_Foo = Define_Type(0, "foo", NOFUNC, sizeof(struct S_Foo), Foo_Equal, Foo_Equal, Foo_Print, NOFUNC); Define_Primitive((Object(*)(...))P_Make_Foo, "make-foo", 0, 0, EVAL); Define_Primitive((Object(*)(...))P_Read_Val, "read-val", 1, 1, EVAL); Define_Primitive((Object(*)(...))P_Write_Val, "write-val!", 2, 2, EVAL); } + diff --git a/examples/CC/constructor.c b/examples/CC/constructor.c index df2d4f2..a2dc560 100644 --- a/examples/CC/constructor.c +++ b/examples/CC/constructor.c @@ -3,24 +3,13 @@ This simple C++ program demonstrates that static constructors (destructors) are invoked by Elk when loading a compiled C++ file (when exiting). -o Compile the program with CC -c -I/usr/elk/include constructor.c, where - /usr/elk is the toplevel directory of your Elk installation. Under - Solaris 2.x (and SysVR4) you also have to specify -pic (-fpic for g++). +o Compile the shared object, for instance: -o Invoke Elk and set the load-libraries to point to the C++ and the - C library, e.g. type something like: + CC -pic -shared -I/usr/elk/include constructor.c -o constructor.so - (set! load-libraries "-L/usr/lang/SC2.0.1 -lC -lc") - or - (set! load-libraries "-R/usr/lang/lib -L/usr/lang/lib -lC -lc") - or just - (set! load-libraries "-lC -lc") - - depending on the platform and the place where the C++ library has - been installed on your system. If you are using g++, you may have - to mention both the g++ library and the gcc library. + g++ -fPIC -shared -I/usr/include/elk constructor.c -o constructor.so -o Now "(load 'constructor.o)", observe the "invoking constructor" message, +o Now "(load 'constructor.so)", observe the "invoking constructor" message, and evaluate "(test)", which should return 3. Terminate the interpreter and observe the "invoking destructor" message. @@ -47,16 +36,16 @@ o If static constructors don't get called when loading compiled C++ files, #include "scheme.h" -#include +#include class C { public: int i; C() { - cerr << "[invoking constructor]" << endl; + std::cerr << "[invoking constructor]" << std::endl; i = 3; } - ~C() { cerr << "[invoking destructor]" << endl; } + ~C() { std::cerr << "[invoking destructor]" << std::endl; } }; C c; @@ -65,10 +54,10 @@ Object P_Test() { return Make_Integer(c.i); } -void elk_init_constructor() { +extern "C" void elk_init_constructor() { Define_Primitive((Object (*)(...))P_Test, "test", 0, 0, EVAL); } -void elk_finit_constructor() { - cerr << "Goodbye." << endl; +extern "C" void elk_finit_constructor() { + std::cerr << "Goodbye." << std::endl; }