Dear Gambit List,
I have a set of datatypes defined with c-define-type based on the GNU Scientific Library. The Gambit-C manual says "For type checking on the Scheme side..." to use the TAG function of the type definition as in
(c-define-type gsl-matrix* (pointer gsl-matrix "gsl-matrix*"))
What is the best way to use this to define a boolean test (e.g. gsl-matrix*?) for this type? I feel like I must be missing something since the explanation of type checking stops with how to define the TAG and how it's printed in the external representation of an object of that type.
For example: ;;gsl-matrix-initialize returns a pointer ;;to a gsl-matrix (define A (gsl-matrix-initialize)) A #<gsl-matrix* 2 0x38f9e89>
Thanks, Joel
Afficher les réponses par date
At 10:56 AM -0500 1/10/08, Joel J. Adamson wrote:
Dear Gambit List,
I have a set of datatypes defined with c-define-type based on the GNU Scientific Library. The Gambit-C manual says "For type checking on the Scheme side..." to use the TAG function of the type definition as in
(c-define-type gsl-matrix* (pointer gsl-matrix "gsl-matrix*"))
IIRC, you only use the tag if you multiple c-define-type that are equivalent.
(c-define-type type1* (pointer type1 #f) (c-define-type type2* (pointer type2 "type") (c-define-type type3* (pointer type3 "type")
Here all 3 types are exchangeable.
What is the best way to use this to define a boolean test (e.g. gsl-matrix*?) for this type? I feel like I must be missing something since the explanation of type checking stops with how to define the TAG and how it's printed in the external representation of an object of that type.
NULL converts to #f, if that's what you're asking.
Stephane Le Cornec coleste@videotron.ca writes:
At 10:56 AM -0500 1/10/08, Joel J. Adamson wrote:
Dear Gambit List,
I have a set of datatypes defined with c-define-type based on the GNU Scientific Library. The Gambit-C manual says "For type checking on the Scheme side..." to use the TAG function of the type definition as in
(c-define-type gsl-matrix* (pointer gsl-matrix "gsl-matrix*"))
IIRC, you only use the tag if you multiple c-define-type that are equivalent.
(c-define-type type1* (pointer type1 #f) (c-define-type type2* (pointer type2 "type") (c-define-type type3* (pointer type3 "type")
Here all 3 types are exchangeable.
Good to know. The difference I noted was that if I leave off the tag, I get the C name "gsl_matrix*" in the external representation of the pointer. If I use the tag, I can make it the more lispy "gsl-matrix*" or "gsl-matrix-pointer". Is that not a compelling reason to use it? In other words, is it a waste to do it except in the case you outlined?
What is the best way to use this to define a boolean test (e.g. gsl-matrix*?) for this type?
[...]
NULL converts to #f, if that's what you're asking.
That was not specifically my question, but it certainly points me in the right direction ;) Phrased in those terms I'm looking for a C procedure (macro?) that returns NULL for only the type I'm querying, i.e. returns anything other than NULL for the intialized datatype.
I'll think about this some more.
Thanks, Joel
Your message prompted me to do some extensions to the FFI's foreign type implementation I was meaning to do for a while.
On 10-Jan-08, at 10:56 AM, Joel J. Adamson wrote:
Dear Gambit List,
I have a set of datatypes defined with c-define-type based on the GNU Scientific Library. The Gambit-C manual says "For type checking on the Scheme side..." to use the TAG function of the type definition as in
(c-define-type gsl-matrix* (pointer gsl-matrix "gsl-matrix*"))
Note that your code is incorrect. It should read
(c-define-type gsl-matrix* (pointer gsl-matrix gsl-matrix*))
What is the best way to use this to define a boolean test (e.g. gsl-matrix*?) for this type?
The new implementation of foreign types (now in the Gambit repository) allows assigning multiple tags to a given foreign type and allows the extraction of the tags from a foreign object:
(c-define-type char* (pointer char (foo bar))) (define f (c-lambda () char* "___result = "hello";")) (define x (f)) (foreign? x) ==> #t (foreign-tags x) ==> (foo bar)
So for your code you could do this:
(c-define-type gsl-matrix* (pointer gsl-matrix gsl-matrix*))
(define (gsl-matrix*? obj) (and (foreign? obj) (equal? (foreign-tags obj) '(gsl-matrix*))))
The ability to specify multiple tags is useful for implementing type hierarchies. For the classical 2D and 3D point example we have:
(c-define-type p2d (pointer point2d (point2d* point3d*))) (define make-point2d (c-lambda (int int) p2d "make_point2d")) (define show-point2d (c-lambda (p2d) void "show_point2d"))
(c-define-type p3d (pointer point3d (point3d*))) (define make-point3d (c-lambda (int int int) p3d "make_point3d"))
(show-point2d (make-point2d 11 22)) (show-point2d (make-point3d 11 22 33))
Note that the definition
(c-define-type p2d (pointer point2d (point2d* point3d*)))
is saying that wherever the type "p2d" is expected, foreign objects with a primary tag of point2d* or point3d* are allowed (the primary tag of a foreign type is the first tag in its list of tags, and is the tag used in the external representation of the foreign object).
Marc
Marc Feeley feeley@iro.umontreal.ca writes:
Your message prompted me to do some extensions to the FFI's foreign type implementation I was meaning to do for a while.
Wow --- I think I'm hooked on Gambit ;)
On 10-Jan-08, at 10:56 AM, Joel J. Adamson wrote:
Dear Gambit List,
I have a set of datatypes defined with c-define-type based on the GNU Scientific Library. The Gambit-C manual says "For type checking on the Scheme side..." to use the TAG function of the type definition as in
(c-define-type gsl-matrix* (pointer gsl-matrix "gsl-matrix*"))
Note that your code is incorrect. It should read
(c-define-type gsl-matrix* (pointer gsl-matrix gsl-matrix*))
Yes, I was typing it from memory; it actually reads like this:
(c-define-type gsl-matrix (type "gsl_matrix" gsl-matrix)) (c-define-type gsl-matrix* (pointer "gsl_matrix" gsl-matrix*))
The only difference being the double-quotation marks around the C type; should I not use them?
What is the best way to use this to define a boolean test (e.g. gsl-matrix*?) for this type?
The new implementation of foreign types (now in the Gambit repository)
Looks like I'll be installing Mercurial ;)
Thanks a huge bunch for your suggestions (and needless to say for updating the code --- open source strikes again).
Joel