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