I'm building an executable that links with an object file that controls a machine via the USB bus.
I have this working OK by linking everything into an executable. But that means I must recompile every time I make a change to my scheme code. Instead, I'd like to be able to load the scheme code at runtime. Originally I wanted to compile my c code into a library so that I could load it with gsi. However i was unable to get that to work.
Poking around in the examples, I found (##repl-debug-main), so I put that at the end of my c-api .scm file. This works well. When I run the executable, I get a repl, and can then load further scheme files as needed.
Is this the recommended way to embed a Gambit repl in a c program? Where can I find this ##repl-debug-main documented? What's the significance of the ## character? Is there a way to pass startup arguments to this repl?
Thanks,
Neil Baylis
Afficher les réponses par date
Neil Baylis wrote:
I'm building an executable that links with an object file that controls a machine via the USB bus.
I have this working OK by linking everything into an executable. But that means I must recompile every time I make a change to my scheme code. Instead, I'd like to be able to load the scheme code at runtime. Originally I wanted to compile my c code into a library so that I could load it with gsi. However i was unable to get that to work.
Well, you could (c-declare "#include ..") the C code into a yourfile.scm file and compile that file to a loadable object (using (compile-file "yourfile.scm") or gsc yourfile.scm) and then load it through (load "yourfile").
(The advantage would be that each time you alter your C code you could recompile and reload it into your running application, too)
See the attached example. Run it like:
in Emacs: C-u M-x run-scheme gsc from the shell: just "gsc"
(begin (compile-file "reload-c-code") (load "reload-c-code"))
"/home/chris/schemedevelopment2/gambit/reload-c-code.o1"
(do-something "Hello")
We're doing something: Hello 0
(do-something "Hello")
We're doing something: Hello 1
(do-something "Hello")
We're doing something: Hello 2
(begin (compile-file "reload-c-code") (load "reload-c-code"))
"/home/chris/schemedevelopment2/gambit/reload-c-code.o2"
(do-something "Hello")
We're doing something: Hello 0
(do-something "Hello")
We're doing something: Hello 1
Now change the string given to fprintf in MyCcode.c and, from the still running gsc process:
(begin (compile-file "reload-c-code") (load "reload-c-code"))
"/home/chris/schemedevelopment2/gambit/reload-c-code.o3"
(do-something "Hello")
We're still doing something: Hello 0
(do-something "World")
We're still doing something: World 1
Poking around in the examples, I found (##repl-debug-main), so I put that at the end of my c-api .scm file. This works well. When I run the executable, I get a repl, and can then load further scheme files as needed.
Is this the recommended way to embed a Gambit repl in a c program? Where can I find this ##repl-debug-main documented?
Probably only in the sources, it's in lib/_repl.scm
What's the significance of the ## character?
See http://dynamo.iro.umontreal.ca/~gambit/wiki/index.php/Namespaces
Is there a way to pass startup arguments to this repl?
As you can see from the sources, no.
There are also ##repl-debug and ##repl procedures being called by the former, check if they do what you want. (Read the sources as examples; as mentioned in the wiki page above, many or generally all of those procedures just segfault if you're feeding them data of the wrong type. You could try recompiling Gambit with (declare (safe)) in the places you want to play with, or maybe in header.scm.)
Christian.
On 9-Feb-08, at 4:18 AM, Neil Baylis wrote:
I'm building an executable that links with an object file that controls a machine via the USB bus.
I have this working OK by linking everything into an executable. But that means I must recompile every time I make a change to my scheme code. Instead, I'd like to be able to load the scheme code at runtime. Originally I wanted to compile my c code into a library so that I could load it with gsi. However i was unable to get that to work.
An example of this is given on page 11 of the Gambit manual. The X11 example (examples/X11-simple) also shows how you can do this.
Briefly, assume you have the Scheme file "s.scm" and the C file "c.c" and header file "c.h" which "s.scm" is interfacing with:
-------------------------------------------------------- ;; File: "s.scm" (c-declare "#include "c.h"") (define square (c-lambda (int) int "square")) -------------------------------------------------------- /* File: "c.h" */ int square (int x); -------------------------------------------------------- /* File: "c.c" */ int square (int x) { return x*x; } --------------------------------------------------------
Then you can simply do this:
% gsc -cc-options "c.c" s.scm
[Note that if you embed the code of c.c in the c-declare of s.scm, you can avoid the -cc-options "c.c"]
then
% gsi s -
(square 10)
100
or
% gsi Gambit v4.2.2
(load "s") (square 10)
100
If you need to include some special header files, or link with a special C library then something like this is needed:
% gsc -cc-options "-I/usr/include/foo c.c" -ld-options "-L/usr/lib/ foo -lfoo" s.scm
Marc
Christian, Marc.. thanks for the info.
I had worked through the examples in the manual, but something wasn't working for me. Anyway, following Marc's instructions, I was able to get my api to link correctly, so I can start it from gsi as I had originally wanted.
It works fine now. Originally, I had been having trouble resolving symbols in the OSX CoreFoundation and IOKit frameworks. I had somehow thought I needed to compile and link my c module separately (using gcc & ld). Now, passing the whole thing to gsc does the trick.
This is the gsc line I ended up with:
gsc -cc-options "ufifo.c" -ld-options "/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation /System/Library/Frameworks/IOKit.framework/IOKit" g-uf-api.scm
My USB interface code is in ufifo.c and its scheme api is in g-uf-api.scm. When I compile this, I get g-uf-api.o1 which I can load from the gsi repl.
Thanks again,
Neil