guile-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Creating modules from C (was: On the deprecated auto-loading of comp


From: Martin Grabmueller
Subject: Re: Creating modules from C (was: On the deprecated auto-loading of compiled-code modules)
Date: Wed, 09 May 2001 17:57:31 +0200

> From: Martin Grabmueller <address@hidden>
> Date: Wed, 09 May 2001 15:59:16 +0200
> 
> I will try to play around with that and post a working example, if I
> succeed.

Okay, I have played now.  I have not reached a clean solution to all
this, but I thought I'd present my results so far anyway.

I have attached the file I used for my experiments.  For convenience,
I implemented my test module as a shared object, to be loaded
dynamically.  If you work with a static module, you can leave out the
dynamic-link and dynamic-call procedure calls, and call
scm_init_test() from your main C module, of course.

The test module consists of one smob function, two C primitives (from
which only one will be exported) and an initialization function.  No
Scheme source file is needed.

After compiling this (I used the snarfer, so you should maybe replace
the #include test.x with the necessary calls to gh_new_procedure and
change the function declarations accordingly -- excuse my laziness), I
had the following Guile session:

  guile> (define d (dynamic-link ".libs/libguile-test-test"))
  guile> (dynamic-call "scm_init_test" d)                    
  guile> (use-modules (my module))                           
  guile> (make-test)
  #<test>
  guile> (test-version)
  <unnamed port>:5:1: In expression (test-version):
  <unnamed port>:5:1: Unbound variable: test-version
  ABORT: (unbound-variable)
  guile> 

[The first two lines are dynamic linking blurb, ignore them for now]

To make the bindings from (my module) available, I have to use
`use-modules', of course.  After that, I can use the procedure
`make-test', but not `test-version'.  This is because the latter is
not included in the list of symbols to be exported in the call to
`module-export!' in the initialization procedure below.

So here is the summary of what I wanted to show:

* You have to create your module with scm_make_module().

* You have to make sure that the module has a public interface, using
  scm_ensure_user_module().

* You have to set your module as the current module.

* You have to add your new bindings, using one of the Guile functions
  for that (scm_make_gsubr, gh_new_procedure).

* You have to export explicitly the procedures to be exported (for
  which there are no C functions, so you have to evaluate Scheme code
  by hand).

* Restore the old current module.

I hope this helps with your particular problem, but there are a few
issues left.  For example, having to evaluate the module-export! form
by hand is a bit strange.

Also, I am not sure whether there is a simple method for achieving the
goal of creating a C only module.

Regards,
  'martin

===File ~/cvs/foo/test/test.c===============================
#include <guile/gh.h>

/* Smob type codes for ... .  */
static int scm_tc16_test = 0;

/* Smob print hook for ... .  */
static int
test_print (SCM test, SCM port, scm_print_state *pstate)
{
  scm_puts ("#<test>", port);
  return 1;
}

SCM_DEFINE (scm_test_version, "test-version", 0, 0, 0, 
            (void),
            "Return version information for this module.")
#define FUNC_NAME s_scm_test_version
{
  return scm_makfrom0str (VERSION);
}
#undef FUNC_NAME

SCM_DEFINE (scm_make_test, "make-test", 0, 0, 0,
            (void),
            "Create a new @code{test} object.")
#define FUNC_NAME s_scm_make_test
{
  SCM_RETURN_NEWSMOB(scm_tc16_test, NULL);
}
#undef FUNC_NAME

void
scm_init_test (void)
{
  SCM my_module = scm_make_module (scm_read_0str ("(my module)"));
  SCM code = scm_read_0str ("(module-export! (resolve-module '(my module)) 
'(make-test))");
  SCM old;

  scm_tc16_test = scm_make_smob_type ("test", 0);
  scm_set_smob_print (scm_tc16_test, test_print);

  old = scm_set_current_module (my_module);
  scm_ensure_user_module (my_module);
#ifndef SCM_MAGIC_SNARFER
#include "test.x"
#endif
  scm_eval (code, my_module);
  scm_set_current_module (old);
}
============================================================



reply via email to

[Prev in Thread] Current Thread [Next in Thread]