Racket function call with C

I have a Racket hw.rkt module:

#lang racket/base (provide hw) (define (hw) (displayln "Hello, world!")) 

I would like to write a C program in which the Racket runtime is embedded and the procedure (hw) is applied.

Here is a sample code that demonstrates how to implement the Racket runtime and apply the procedure that is in racket/base , or read and evaluate the S-expression, but I was not lucky to modify this code to allow access to the procedure (hw) .

This page seems to say that you can do what I want to do by first compiling hw.rkt to hw.c using raco ctool --c-mods , and this works fine when I try it, but I still I can’t access the procedure (hw) .

If someone could post a complete sample program or just describe which C features to use, I would really appreciate it. From there I can find out the rest.


Editing to provide examples of the things I've tried.

I modified the sample program to get rid of the "evaluate command line arguments" bit and skip directly to REPL so I can experiment. Thus (with "hw.c" the result of running raco ctool --c-mods hw.c ++libs racket/base hw.rkt ):

 #define MZ_PRECISE_GC #include "scheme.h" #include "hw.c" static int run(Scheme_Env *e, int argc, char *argv[]) { Scheme_Object *curout = NULL, *v = NULL, *a[2] = {NULL, NULL}; Scheme_Config *config = NULL; int i; mz_jmp_buf * volatile save = NULL, fresh; MZ_GC_DECL_REG(8); MZ_GC_VAR_IN_REG(0, e); MZ_GC_VAR_IN_REG(1, curout); MZ_GC_VAR_IN_REG(2, save); MZ_GC_VAR_IN_REG(3, config); MZ_GC_VAR_IN_REG(4, v); MZ_GC_ARRAY_VAR_IN_REG(5, a, 2); MZ_GC_REG(); declare_modules(e); v = scheme_intern_symbol("racket/base"); scheme_namespace_require(v); config = scheme_current_config(); curout = scheme_get_param(config, MZCONFIG_OUTPUT_PORT); save = scheme_current_thread->error_buf; scheme_current_thread->error_buf = &fresh; if (scheme_setjmp(scheme_error_buf)) { scheme_current_thread->error_buf = save; return -1; /* There was an error */ } else { /* read-eval-print loop, uses initial Scheme_Env: */ a[0] = scheme_intern_symbol("racket/base"); a[1] = scheme_intern_symbol("read-eval-print-loop"); v = scheme_dynamic_require(2, a); scheme_apply(v, 0, NULL); scheme_current_thread->error_buf = save; } MZ_GC_UNREG(); return 0; } int main(int argc, char *argv[]) { return scheme_main_setup(1, run, argc, argv); } 

Things that don't work (and their error messages):

Call (hw) from REPL

 hw: undefined: cannot reference undefined identifier context...: /usr/local/share/racket/collects/racket/private/misc.rkt:87:7 

((dynamic-require 'hw 'hw))

 standard-module-name-resolver: collection not found for module path: hw collection: "hw" in collection directories: context...: show-collection-err standard-module-name-resolver /usr/local/share/racket/collects/racket/private/misc.rkt:87:7 

((dynamic-require "hw.rkt" 'hw))

 standard-module-name-resolver: collection not found for module path: racket/base/lang/reader collection: "racket/base/lang" in collection directories: context...: show-collection-err standard-module-name-resolver standard-module-name-resolver /usr/local/share/racket/collects/racket/private/misc.rkt:87:7 

Editing Example Code

 v = scheme_intern_symbol("racket/base"); scheme_namespace_require(v); v = scheme_intern_symbol("hw"); scheme_namespace_require(v); 

Mistake:

 standard-module-name-resolver: collection not found for module path: hw collection: "hw" in collection directories: context...: show-collection-err standard-module-name-resolver SIGSEGV MAPERR sicode 1 fault on addr 0xd0 Aborted 

(Segfault, probably because I did not check the value of 'v' before trying scheme_namespace_require it.)

Editing the mk example code. 2

 v = scheme_intern_symbol("racket/base"); scheme_namespace_require(v); v = scheme_intern_symbol("hw.rkt"); scheme_namespace_require(v); 

Mistake:

 hw.rkt: bad module path in: hw.rkt context...: standard-module-name-resolver SIGSEGV MAPERR sicode 1 fault on addr 0xd0 Aborted 

(re: segfault: as above)

Editing the mk example code. 3

 v = scheme_intern_symbol("racket/base"); scheme_namespace_require(v); v = scheme_intern_symbol("./hw.rkt"); scheme_namespace_require(v); 

(as mentioned above)

Editing the mk example code. 4

 /* read-eval-print-loop, uses initial Scheme_Env: */ a[0] = scheme_intern_symbol("hw"); a[1] = scheme_intern_symbol("hw"); v = scheme_dynamic_require(2, a); 

(like mk.1, save segfault)

Editing the mk example code. 5

 /* read-eval-print loop, uses initial Scheme_Env: */ a[0] = scheme_intern_symbol("hw"); a[1] = scheme_eval(a[0], e); scheme_apply(a[1], 0, NULL); 

Mistake:

 hw: undefined; cannot reference undefined identifier 
+8
c racket embedding
source share
1 answer

Answered by Matthew Flatt here . When using dynamic-require I needed to specify the module name twice, and not once. Thanks to Dr. Flit for help.

+3
source share

All Articles