Mam moduł Rakieta hw.rkt:Funkcja połączenia Rakieta z C
#lang racket/base
(provide hw)
(define (hw) (displayln "Hello, world!"))
Chciałbym napisać program w C, który osadza runtime Racket i stosuje procedurę (hw)
.
Istnieje przykład kodu here, który demonstruje, jak osadzić środowisko wykonawcze rakiety i zastosować procedurę, która jest w racket/base
, lub czytać i oceniać wyrażenie S, ale nie miałem szczęścia, modyfikując ten kod, aby umożliwić dostęp do procedura (hw)
.
This page zdaje się mówić, że jest możliwie robić to, co chcę robić przez pierwsze kompilacji hw.rkt do hw.c użyciu raco ctool --c-mods
i to działa dobrze, gdy próbuję go, ale nadal nie mogę faktycznie uzyskać dostęp do procedury (hw)
.
Jeśli ktoś mógłby opublikować kompletny przykładowy program lub po prostu opisać, które funkcje C należy użyć, byłbym bardzo wdzięczny. Stamtąd mogę wymyślić resztę.
Edytowanie w celu przedstawienia przykładów rzeczy, które próbowałem.
Zmodyfikowałem przykładowy program, aby pozbyć się bitów "Oceń argumenty wiersza poleceń" i przejdź bezpośrednio do REPL, aby móc eksperymentować. W ten sposób (z "hw.c" Wynikiem działania 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);
}
rzeczy, które nie działają (i komunikaty o błędach swoje):
Wywołanie (hw)
z 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
Edycja przykładowy kod
v = scheme_intern_symbol("racket/base");
scheme_namespace_require(v);
v = scheme_intern_symbol("hw");
scheme_namespace_require(v);
Błąd:
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 był prawdopodobnie dlatego, że nie sprawdzić wartość "v" być przed próbowaniem do scheme_namespace_require
it.)
Edytowanie przykładowego kodu mk.2
v = scheme_intern_symbol("racket/base");
scheme_namespace_require(v);
v = scheme_intern_symbol("hw.rkt");
scheme_namespace_require(v);
błędu:
hw.rkt: bad module path
in: hw.rkt
context...:
standard-module-name-resolver
SIGSEGV MAPERR sicode 1 fault on addr 0xd0
Aborted
(Przedmiot segfault: jak wyżej)
Edycja mk przykład kodu. 3
v = scheme_intern_symbol("racket/base");
scheme_namespace_require(v);
v = scheme_intern_symbol("./hw.rkt");
scheme_namespace_require(v);
(jak wyżej)
Edycja mk przykład kodu. 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);
(jak MK. 1, należy zapisać segfault)
Edycja mk przykład kodu. 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);
błędu:
hw: undefined;
cannot reference undefined identifier