[Top][All Lists]
[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/