guile-user
[Top][All Lists]
Advanced

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

Re: Newbie Qs: c pointers


From: Richard Guenther
Subject: Re: Newbie Qs: c pointers
Date: Sat, 18 Aug 2001 16:23:15 +0200 (CEST)

On Sat, 18 Aug 2001, Matthew wrote:

> I'm using Guile 1.4 as a scripting / extension language for a C 
> application, with Guile calling various C interface functions.
> 
> 1. How can I return pointers to Guile? I don't want to do anything with 
> them except pass them back to the C side again later.
> 
> 2. Can anyone recommend an exisiting app that does this kind of thing, 
> that I can study? (I've spent some time going over GnuCash, but it's a 
> bit hairy!)

GLAME uses a set of smobs which just contain a pointer, use like

long pipe_smob_tag;
#define scm2pipe(s) ((filter_pipe_t *)scm2pointer(s, pipe_smob_tag))
#define pipe2scm(p) pointer2scm(p, pipe_smob_tag)
#define scminvalidatepipe(s) scminvalidatepointer(s, pipe_smob_tag)
#define pipe_p(s) (SCM_NIMP(s) && SCM_CAR(s) == pipe_smob_tag)

and somewhere in init:

        pipe_smob_tag = scm_make_smob_type("pipe",
                                           sizeof(struct pointer_smob));
        scm_set_smob_print(pipe_smob_tag, print_pointer);
        scm_set_smob_equalp(pipe_smob_tag, equalp_pointer);

The common code is:

/* SMOB for generic C pointer - for internal use only.
 */
 
struct pointer_smob {
        void *pointer;
};
#define SCM2POINTERSMOB(s) ((struct pointer_smob *)SCM_SMOB_DATA(s))
 
int print_pointer(SCM pointer_smob, SCM port, scm_print_state *pstate);
SCM equalp_pointer(SCM pointer_smob1, SCM pointer_smob2);
SCM pointer2scm(void *pointer, long smob_tag);
void *scm2pointer(SCM pointer_smob, long smob_tag);
void scminvalidatepointer(SCM pointer_smob, long smob_tag);

int print_pointer(SCM pointer_smob, SCM port, scm_print_state *pstate)
{
        struct pointer_smob *pointer = SCM2POINTERSMOB(pointer_smob);
        char buf[256];
 
        snprintf(buf, 255, "#<pointer %p>", pointer->pointer);
        scm_puts(buf, port);
 
        return 1;
}
 
SCM equalp_pointer(SCM pointer_smob1, SCM pointer_smob2)
{
        struct pointer_smob *pointer1 = SCM2POINTERSMOB(pointer_smob1);
        struct pointer_smob *pointer2 = SCM2POINTERSMOB(pointer_smob2);
 
        if (pointer1->pointer == pointer2->pointer)
                return SCM_BOOL_T;
        return SCM_BOOL_F;
}
 
SCM pointer2scm(void *pointer, long smob_tag)
{
        struct pointer_smob *smob;
        SCM pointer_smob;
 
        if (!pointer)
                return SCM_BOOL_F;
 
        smob = (struct pointer_smob *)malloc(sizeof(struct pointer_smob));
        smob->pointer = pointer;
 
        SCM_NEWSMOB(pointer_smob, smob_tag, smob);
 
        return pointer_smob;
}
 
void *scm2pointer(SCM pointer_smob, long smob_tag)
{
        SCM_ASSERT((SCM_NIMP(pointer_smob)
                    && SCM_CAR(pointer_smob) == smob_tag),
                   pointer_smob, SCM_ARG1, "scm2pointer");
        return SCM2POINTERSMOB(pointer_smob)->pointer;
}
 
void scminvalidatepointer(SCM pointer_smob, long smob_tag)
{
        struct pointer_smob *pointer = SCM2POINTERSMOB(pointer_smob);
 
        SCM_ASSERT((SCM_NIMP(pointer_smob) 
                    && SCM_CAR(pointer_smob) == smob_tag),
                   pointer_smob, SCM_ARG1, "scminvalidatepointer");
 
        pointer->pointer = NULL;
}

--
Richard Guenther <address@hidden>
WWW: http://www.tat.physik.uni-tuebingen.de/~rguenth/
The GLAME Project: http://www.glame.de/




reply via email to

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