chicken-users
[Top][All Lists]
Advanced

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

Re: [Chicken-users] question on C types


From: felix
Subject: Re: [Chicken-users] question on C types
Date: Mon, 24 Nov 2003 18:20:24 +0100
User-agent: Opera7.11/Linux M2 build 406

On 24 Nov 2003 17:42:09 +0100, Joerg F. Wittenberger <address@hidden> wrote:

Hi,

somehow I can't understand the fine manual.  I want to code some parts
in C and can't interface.

(subtle point about the manual taken ;-)


The idea is to have 'result' hold a reference to some memory, which is
going to be opaque to the scheme side.  I don't need any type
checking, actually I don't want any.  I tried:

(let ((result (##sys#allocate-vector size #f 0 #f)))
((foreign-lambda*
void
((c-pointer line) (integer size))
"int *p=line; int i; for(i=0; i<size; ++i) p[i]=i;")
result size)
result))

But I get:

Error: bad argument type - not a pointer: #(0 0)

So apparently I better use something else instead of
'##sys#allocate-vector' ???  And what will I have to do to get rid of
the type check eventually?


First: Never use "##sys#allocate-vector", it's for internal purposes only.

You can use `pointer' instead of `c-pointer' as the argument type,
this will pass a pointer to the raw data section of a Scheme object
(in this case a pointer to C_words holding fixnums). Your example will break, though, since you can not convert the numbers into a format
Scheme recognizes.

Another approach (if you want to have a number vector) is to use
SRFI-4 vectors and pass them as of the proper type:

(declare (uses srfi-4)) ; or (require 'srfi-r), if your registry is set up.

(let ([result (make-s32vector size)])
 ((foreign-lambda* void ([s32vector line] [int size])
"int *p = line; int i; for(i = 0; i < size; ++i) p[ i ] = i;") result size)
 result)

If the object should be opaque (in the sense that it shouldn't print
as a vector or something recognizable), you can wrap it into a record:

(define-record opaque line)

(define-foreign-type opaque s32vector opaque-line)

(let ([result (make-opaque (make-s32vector size))])
 ((foreign-lambda* void ([opaque line] [int size])
    "int *p = line; int i; for(i = 0; i < size; ++i) p[ i ] = i;")
  result size) )

If the object should be opaque and if it contains raw C data,
then allocate it in C and pass it around the Scheme world as a c-pointer:

#>!
static void *make_it(int size) { return (void *)malloc(size * sizeof(int)); }
static void init_it(void *ptr, int size) {
 int *p = (int *)ptr;
 int i;
 for(i = 0; i < size; ++i) p[ i ] = i;
}
void free(void *);
<#

(let ([result (make_it size)])
 (set-finalizer! result free)   ; usual caveats about finalizers apply
 (init_it result size)
 result)


cheers,
felix





reply via email to

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