From: Harald Kucharek
Subject: Calling C function from LCL
Date:
Message-ID: <Bt8G1E.229@iai.kfk.de>
I have the following little C program:
#include <stdio.h>
int
ca(my_array)
int my_array[2][2];
{
int i, j;
int result = 0;
for (i = 0; i < 2; ++i) {
for (j = 0; j < 2; ++j) {
printf("%d\n", my_array[i][j]);
result += my_array[i][j];
}
} return (result);
}
which I want to call from LISP (I am using Lucid Common Lisp 4.0.1 on a SPARCstation330)
I define:
(def-foreign-function (run-ca (:return-type :signed-32bit)
(:name "_ca")
(:language :c))
(my_array (:array :signed-32bit (4))))
(load-foreign-files "/home/harry/C/ca.o")
which gives the output:
;;; Loading foreign object file "C/ca.o"
;;; Reading library file "/lib/libc.a"
;;; Reading library file "/lib/libm.a"
;;; Warning: The following foreign symbols are undefined: (__DYNAMIC)
NIL
(setq a (make-array '(2 2) :element-type 'integer))
(loop for i from 0 to 1 do
(loop for j from 0 to 1 do
(setf (aref a i j) (+ i j))))
(run-ca a)
which outputs:
0
4
4
8
16
Questions:
1) What is this missing symbol __DYNAMIC
2) The contents of the array are all multiplied by 4. Has this something
to do with the type of the lisp object? I always thought, it is coded in the high order
bits of the data.
3) What is wrong in my declaration of the foreign function, that make all these things happen?
Thanks for any suggestions.
Harald
Harald Kucharek ($B>.?M(J), Nuclear Research Center Karlsruhe, IDT
7514 Eggenstein-Leopoldshafen, Germany
Internet: ·····@issun1.kfk.de Phone: +49 7247 825706
In article <··········@iai.kfk.de> ·····@issun1.kfk.de (Harald Kucharek) writes:
I have the following little C program:
...
ca(my_array)
int my_array[2][2];
..
which I want to call from LISP (I am using Lucid Common Lisp 4.0.1 on a SPARCstation330)
I define:
(def-foreign-function (run-ca (:return-type :signed-32bit)
...(my_array (:array :signed-32bit (4))))
...
(setq a (make-array '(2 2) :element-type 'integer))
...
Questions:
1) What is this missing symbol __DYNAMIC
2) The contents of the array are all multiplied by 4. Has this something
to do with the type of the lisp object? I always thought, it is coded in the high order
bits of the data.
3) What is wrong in my declaration of the foreign function, that make all these things happen?
Harald
The problem should be in your make-array. The type 'integer is very
general and results in all elements being tagged. Instead, use
'(signed-byte 32). Also, Lucid seems to use the low order two bits
for type tags. I don't know what __DYNAMIC is.
Also, I don't think 'fixnum even gives you what you want. Each fixnum
in the array will have tag bits. (This is reaching back a ways for me
and could easily be wrong.)
doug
--------------------------------------------------------------------
Doug Morgan, ····@ads.com, (415) 960-7300
Advanced Decision Systems (a division of Booz-Allen & Hamilton Inc.)
1500 Plymouth St., Mountain View, CA 94043-1230
--------------------------------------------------------------------
In article <··········@iai.kfk.de> ·····@issun1.kfk.de writes:
>1) What is this missing symbol __DYNAMIC
You can ignore that. It's related to Sun's dynamic linking implementation,
but Lucid's FFI only loads static libraries.
>2) The contents of the array are all multiplied by 4. Has this something
> to do with the type of the lisp object? I always thought, it is coded in the high order
> bits of the data.
C ints correspond to Lisp fixnums, but you passed an untyped array. Lucid
(and many other Lisp implementations) puts some tag bits information in the
low-order two bits of objects; they're ordinarily unused, since all the
types that are accessed through pointers require full-word alignment.
Fixnums have the type tags 00 (positive fixnum) and 11 (negative fixnum);
this has the property that the tagged value is the result of an arithmetic
shift of the untagged value, which allows them to be added without
untagging, and multiplied by shifting the result rather than the arguments.
The arrays you pass to the foreign function must be created with
(make-array 4 :element-type 'fixnum)
>3) What is wrong in my declaration of the foreign function, that make all these things happen?
Nothing.
--
Barry Margolin
System Manager, Thinking Machines Corp.
······@think.com {uunet,harvard}!think!barmar
······@think.com (Barry Margolin) writes:
> Fixnums have the type tags 00 (positive fixnum) and 11 (negative fixnum);
> this has the property that the tagged value is the result of an arithmetic
> shift of the untagged value, which allows them to be added without
> untagging, and multiplied by shifting the result rather than the arguments.
Are those tags on the low end or high end of the word? If they are on
the low end, then how does adding two negative fixnums result in
anything useful (xxx11 + xxx11 = xxx10)? If they are on the high end,
where does the shift come in?
We [CMU Common Lisp, that is] use the low three bits as a type-tag,
but have 000 for even fixnums and 100 for odd fixnums. In other
words, if the low two bits are 00 then it is a fixnum with the value
in the upper 30 bits. The implicit multiplication by 4 is handy when
accessing arrays of word (4 byte) sized objects: it's pre-scaled.
-William Lott
CMU Common Lisp Group
In article <··················@cs.cmu.edu> ············@cs.cmu.edu writes:
We [CMU Common Lisp, that is] use the low three bits as a type-tag,
but have 000 for even fixnums and 100 for odd fixnums.
That's exactly the same representation as in Lucid, at least on the
SPARC.
The implicit multiplication by 4 is handy when accessing arrays of
word (4 byte) sized objects: it's pre-scaled.
Yes; this can make vector-intensive code faster than corresponding C
code in many cases... (even if the code has been naively translated
from C to Common Lisp. I think the "Triangle" Gabriel benchmark works
that way :-)
--
Simon.