mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-02 21:10:27 +02:00
* strings.c (scm_c_string2str): New function. Converts a given Scheme string into a C string. Also put in two THINKME's regarding the malloc policy for the missing converter routines.
138 lines
5.2 KiB
Text
138 lines
5.2 KiB
Text
* Intro / Index (last modified: $Date: 2001-12-08 12:50:37 $)
|
|
|
|
This working document explains the design of the libguile API,
|
|
specifically the interface to the C programming language.
|
|
Note that this is NOT an API reference manual.
|
|
|
|
- Motivation
|
|
- History
|
|
- Decisions
|
|
- gh_ removal
|
|
- malloc policy
|
|
- [add here]
|
|
|
|
|
|
* Motivation
|
|
|
|
The file goals.text says:
|
|
|
|
Guile's primary aim is to provide a good extension language
|
|
which is easy to add to an application written in C for the GNU
|
|
system. This means that it must export the features of a higher
|
|
level language in a way that makes it easy not to break them
|
|
from C code.
|
|
|
|
Although it may no longer be a "primary aim", creating a stable API is
|
|
important anyway since without something defined, people will take libguile
|
|
and use it in ad-hoc ways that may cause them trouble later.
|
|
|
|
|
|
* History
|
|
|
|
The initial (in ttn's memory, which only goes back to guile-1.3.4) stab at an
|
|
API was known as the "gh_ interface", which provided "high-level" abstraction
|
|
to libguile w/ the premise of supporting multiple implementations at some
|
|
future date. In practice this approach resulted in many gh_* objects being
|
|
very slight wrappers for the underlying scm_* objects, so eventually this
|
|
maintenance burden outweighed the (as yet unrealized) hope for alternate
|
|
implementations, and the gh_ interface was deprecated starting in guile-1.5.x.
|
|
|
|
Starting w/ guile-1.7.x, in concurrence w/ an effort to make libguile
|
|
available to usloth windows platforms, the naked library was once again
|
|
dressed w/ the "SCM_API interface".
|
|
|
|
|
|
* Decisions
|
|
|
|
** gh_ removal
|
|
|
|
At some point, we need to remove gh_ entirely: guile-X.Y.Z.
|
|
|
|
** malloc policy
|
|
|
|
Here's a proposal by ela:
|
|
|
|
I would like to propose the follow gh_() equivalents:
|
|
|
|
gh_scm2newstr() -> scm_string2str() in string.[ch]
|
|
gh_symbol2newstr() -> scm_symbol2str() in symbol.[ch]
|
|
|
|
Both taking the (SCM obj, char *context) and allocating memory via
|
|
scm_must_malloc(). Thus the user can safely free the returned strings
|
|
with scm_must_free(). The latter feature would be an improvement to the
|
|
previous gh_() interface functions, for which the user was told to free()
|
|
them directly. This caused problems when libguile.so used libc malloc()
|
|
and the calling application used its own standard free(), which might not
|
|
be libc free().
|
|
|
|
It seems to address the general question of: How should client programs use
|
|
malloc with respect to libguile? Some specific questions:
|
|
|
|
* Do you like the names of the functions? Maybe they should be named
|
|
scm_c_*() instead of scm_*().
|
|
* Do they make sense?
|
|
* Should we provide something like scm_c_free() for pointers returned by
|
|
these kind of functions?
|
|
|
|
The first proposal regarding a malloc policy has been rejected for the
|
|
following resons:
|
|
|
|
That would mean, users of guile - even on non M$ systems - would have to
|
|
keep track where their memory came from?
|
|
Assume there are users which have some kind of hash table where they store
|
|
strings in. The hash table is responsible for removing entries from the
|
|
table. Now, if you want to put strings from guile as well as other
|
|
strings into that table you would have to store a pointer to the
|
|
corresponding version of 'free' with every string? We should demand such
|
|
coding from all guile users?
|
|
|
|
The proposal itself read: For a clean memory interface of a client program
|
|
to libguile we use the following functions from libguile:
|
|
|
|
* scm_c_malloc -- should be used to allocate memory returned by some
|
|
of the SCM to C converter functions in libguile if the
|
|
client program does not supply memory
|
|
* scm_c_free -- must be used by the client program to free the memory
|
|
returned by the SCM to C converter functions in
|
|
libguile if the client program did not supply a buffer
|
|
* scm_c_realloc -- to be complete, do not know a real purpose yet
|
|
|
|
|
|
Yet another proposal regarding this problem reads as follows: We could make
|
|
life easier, if we supplied the following:
|
|
|
|
[in gc.h]
|
|
typedef void * (* scm_t_malloc_func) (size_t);
|
|
typedef void (* svz_t_free_func) (void *);
|
|
SCM_API scm_t_malloc_func scm_c_malloc;
|
|
SCM_API scm_t_free_func scm_c_free;
|
|
|
|
[in gc.c]
|
|
{
|
|
/* At some library initialization point. */
|
|
scm_c_malloc = malloc;
|
|
scm_c_free = free;
|
|
}
|
|
|
|
Then the SCM to C converters allocating memory to store their results use
|
|
scm_c_malloc() instead of simply malloc(). This way all libguile/Unix users
|
|
can stick to the previous free() policy, saying that you need to free()
|
|
pointers delivered by libguile. On the other hand M$-Windows users can pass
|
|
their own malloc()-function-pointer to the library and use their own free()
|
|
then. Basically this can be achieved in the following order:
|
|
|
|
{
|
|
char *str;
|
|
scm_boot_guile (...);
|
|
scm_c_malloc = malloc;
|
|
str = scm_c_string2str (obj, NULL, NULL);
|
|
free (str);
|
|
}
|
|
|
|
This policy is still discussed:
|
|
If there is one global variable scm_c_malloc, then setting it within one
|
|
thread may interfere with another thread that expects scm_c_malloc to be
|
|
set differently. In other words, you would have to introduce some locking
|
|
mechanism to guarantee that the sequence of setting scm_c_malloc and
|
|
calling scm_string2str can not be interrupted by a different thread that
|
|
sets scm_c_malloc to a different value.
|