Discussion:
How to pass the address of an pointer object to c?
Fis Trivial
2018-04-01 10:22:25 UTC
Permalink
Hi, all.
I'am trying a wrap a math library written in c with guile scheme. Here
is an example declaration of c type and function in that math library:

typedef void* array;
typedef int err;

err randu(array* result, int ndims, long long *dims, dtype type);



The problem is I want to create a void* (aka array), and pass its
address (aka array*) to the underlying c function for modification. Here
the /array/ type acts as a handle.

I tried the following scheme code:

(let* ([val (make-pointer 0)] ; void* val = 0
[&val (make-pointer (object-address val))] ; a pointer points to val?
[randu (pointer->procedure int
; a function generating random matrix.
(dynamic-func "randu" backend)
; result, ndims, dims, type
(list '* uint32 '* int))]
; dims is an byte-vector representing c array, 0 represents an
; enum value in c.
(randu &val 4 dims 0)))


But when I use gdb to watch the values in c code of randu with:
print *result

and gdb displayed: 0x1f,
while it should be 0 as defined in scheme code.

Is there anything I did wrong? Or there are other ways around? I want to
do it in scheme, otherwise I have to wrap every c functions.

Thanks. :)
Neil Jerram
2018-04-01 12:13:57 UTC
Permalink
Post by Fis Trivial
Hi, all.
I'am trying a wrap a math library written in c with guile scheme. Here
typedef void* array;
typedef int err;
err randu(array* result, int ndims, long long *dims, dtype type);
The problem is I want to create a void* (aka array), and pass its
address (aka array*) to the underlying c function for modification. Here
the /array/ type acts as a handle.
(let* ([val (make-pointer 0)] ; void* val = 0
[&val (make-pointer (object-address val))] ; a pointer points to val?
[randu (pointer->procedure int
; a function generating random matrix.
(dynamic-func "randu" backend)
; result, ndims, dims, type
(list '* uint32 '* int))]
; dims is an byte-vector representing c array, 0 represents an
; enum value in c.
(randu &val 4 dims 0)))
print *result
and gdb displayed: 0x1f,
while it should be 0 as defined in scheme code.
Is there anything I did wrong? Or there are other ways around? I want to
do it in scheme, otherwise I have to wrap every c functions.
Thanks. :)
Would it work for you to use `%null-pointer' ?

From `(guile) Foreign Variables':

-- Scheme Variable: %null-pointer
A foreign pointer whose value is 0.

Best wishes,
Neil
Matt Wette
2018-04-01 13:19:41 UTC
Permalink
Post by Fis Trivial
Hi, all.
I'am trying a wrap a math library written in c with guile scheme. Here
typedef void* array;
typedef int err;
err randu(array* result, int ndims, long long *dims, dtype type);
The problem is I want to create a void* (aka array), and pass its
address (aka array*) to the underlying c function for modification. Here
the /array/ type acts as a handle.
(let* ([val (make-pointer 0)] ; void* val = 0
[&val (make-pointer (object-address val))] ; a pointer points to val?
[randu (pointer->procedure int
; a function generating random matrix.
(dynamic-func "randu" backend)
; result, ndims, dims, type
(list '* uint32 '* int))]
; dims is an byte-vector representing c array, 0 represents an
; enum value in c.
(randu &val 4 dims 0)))
print *result
and gdb displayed: 0x1f,
while it should be 0 as defined in scheme code.
Is there anything I did wrong? Or there are other ways around? I want to
do it in scheme, otherwise I have to wrap every c functions.
Thanks. :)
(let* ((val (make-bytevector (sizeof '*)))
         (&val (bytevector->pointer))
         ...

Loading...