2016-03-29 15 views
8

Tôi có một mô-đun hw.rkt vợt:Gọi chức năng vợt từ C

#lang racket/base 

(provide hw) 

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

Tôi muốn viết một chương trình C nhúng thời gian chạy vợt và áp dụng các thủ tục (hw).

Có mã ví dụ here minh họa cách nhúng thời gian chạy Racket và áp dụng quy trình trong racket/base hoặc đọc và đánh giá biểu thức S, nhưng tôi không có may mắn sửa đổi mã này để cho phép truy cập thủ tục (hw).

This page dường như nói rằng nó là thể để làm những gì tôi muốn làm bằng cách đầu tiên biên soạn hw.rkt để hw.c sử dụng raco ctool --c-mods, và điều này chỉ hoạt động tốt khi tôi thử nó, nhưng tôi vẫn không thể thực sự truy cập thủ tục (hw).

Nếu ai đó có thể đăng chương trình ví dụ hoàn chỉnh hoặc chỉ mô tả các chức năng C sẽ sử dụng, tôi sẽ rất đánh giá cao. Từ đó tôi có thể tìm ra phần còn lại.


Chỉnh sửa để cung cấp ví dụ về những điều tôi đã thử.

Tôi đã sửa đổi chương trình mẫu để loại bỏ "đánh giá đối số dòng lệnh" và bỏ qua thẳng đến REPL để tôi có thể thử nghiệm. Do đó (với "hw.c" là kết quả của chạy 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); 
} 

Những điều đó không làm việc (và thông báo lỗi của họ):

Calling (hw) từ 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 

Chỉnh sửa mã ví dụ

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

Lỗi:

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 

(Các segfault có lẽ vì tôi không kiểm tra giá trị của 'v' là fore cố gắng để scheme_namespace_require nó.)

Chỉnh sửa mã ví dụ mk.2

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

Lỗi:

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

(re: segfault: như trên)

Việc chỉnh sửa mk mã ví dụ. 3

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

(như trên)

Việc chỉnh sửa mk mã ví dụ. 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); 

(như mk. 1, lưu segfault)

Việc chỉnh sửa mk mã ví dụ. 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); 

Lỗi:

hw: undefined; 
cannot reference undefined identifier 

Trả lời

3

Giải đáp của Matthew Flatt here. Khi sử dụng dynamic-require, tôi cần báo giá tên của mô đun hai lần, không phải một lần. Cảm ơn Tiến sĩ Flatt vì sự giúp đỡ của họ.

Các vấn đề liên quan