2016-03-29 48 views
8

我有一個球拍模塊hw.rkt:呼叫球拍功能由C

#lang racket/base 

(provide hw) 

(define (hw) (displayln "Hello, world!")) 

我還想寫嵌入球拍運行時和應用程序(hw)一個C程序。

有一個示例代碼here演示瞭如何嵌入Racket運行時並應用racket/base中的過程,或者讀取和評估S表達式,但我沒有運氣修改此代碼以允許訪問(hw)程序。

This page似乎是說,這是可能做什麼,我想先編譯hw.rkt使用raco ctool --c-mods到hw.c做,當我嘗試這工作得很好,但我現在還不能實際訪問(hw)程序。

如果有人可以發佈一個完整的示例程序,或簡單地描述使用哪個C函數,我會非常感激。從那裏我可以找出其餘的。


編輯提供我嘗試過的東西的例子。

我修改了示例程序以擺脫「評估命令行參數」位並直接跳到REPL,以便我可以嘗試。因此(與 「hw.c」 運行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); 
} 

的事情,不工作(和它們的錯誤消息):

從REPL

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

((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 

編輯示例代碼

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

錯誤:

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 

(段錯誤的可能是因爲我沒有檢查的價值'v'是試圖scheme_namespace_require吧。)

編輯示例代碼mk。2

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

錯誤:

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

(重:段錯誤:如上)

編輯示例代碼MK。 3

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

(如上)

編輯示例代碼MK。 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); 

(如MK 1,保存段錯誤)

編輯示例代碼MK。 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); 

錯誤:

hw: undefined; 
cannot reference undefined identifier 

回答

3

由Matthew弗拉特here回答。當使用dynamic-require時,我需要兩次引用模塊的名稱,而不是一次。感謝弗拉特博士的幫助。