From: Dave Roberts
Subject: Trouble with compiled file using UFFI
Date: 
Message-ID: <Y7mkc.2163$NI6.450606@attbi_s01>
Okay, so I'm working on my DNS resolver library. Everything works peachy
under SBCL, but I'm having trouble with CMUCL. In particular, I'm using
UFFI to load the Linux resolver.so library and then define a foreign
function with the following two forms:

(uffi:load-foreign-library #p"/usr/lib/libresolv.so"
                             :supporting-libraries '("c"))
                                                                                
(uffi:def-function ("res_query" res-query-c)
                   ((dname (:cstring))
                    (class :int)
                    (type :int)
                    (answer (* :unsigned-byte))
                    (anslen :int))
                   :returning :int)

With SBCL, this works great. I have packaged up the library and you can
download it via asdf-install (though it looks like the recent CLiki
restoration blew away my page there, so you'll have to download it directly
from http://www.findinglisp.com/packages/resolver/resolver-latest.tar.gz).

The problem starts when you try to use CMUCL. Everything works. If you have
asdf and asdf-install, you can download it and install it. Asdf will try to
compile all the files the first time it is loaded. This works great, right
up until the time when CMUCL tries to the load the .x86f file. Then I get:

* (asdf:oos 'asdf:load-op :resolver)
 
; loading system definition from
; /home/dave/.asdf-install-dir/systems/resolver.asd into
; #<The ASDF1183 package, 0/9 internal, 0/9 external>
; Loading #p"/home/dave/.asdf-install-dir/site/resolver-0.2/resolver.asd".
; registering #<SYSTEM :RESOLVER {48873835}> as RESOLVER
; [GC threshold exceeded with 12,015,824 bytes in use.  Commencing GC.]
; [GC completed with 3,737,944 bytes retained and 8,277,880 bytes freed.]
; [GC will next occur when at least 15,737,944 bytes are in use.]
; loading system definition from
/home/dave/.asdf-install-dir/systems/uffi.asd
; into #<The ASDF1186 package, 0/9 internal, 0/9 external>
; Loading #p"/home/dave/.asdf-install-dir/site/uffi-1.4.12/uffi.asd".
; registering #<SYSTEM UFFI {48117DDD}> as UFFI
; Loading
#p"/home/dave/.asdf-install-dir/site/uffi-1.4.12/src/package.x86f".
; Loading
#p"/home/dave/.asdf-install-dir/site/uffi-1.4.12/src/primitives.x86f".;
Loading #p"/home/dave/.asdf-install-dir/site/uffi-1.4.12/src/objects.x86f".
; Loading
#p"/home/dave/.asdf-install-dir/site/uffi-1.4.12/src/aggregates.x86f".;
Loading
#p"/home/dave/.asdf-install-dir/site/uffi-1.4.12/src/functions.x86f".
; Loading
#p"/home/dave/.asdf-install-dir/site/uffi-1.4.12/src/strings.x86f".
; Loading
#p"/home/dave/.asdf-install-dir/site/uffi-1.4.12/src/libraries.x86f".
; Loading #p"/home/dave/.asdf-install-dir/site/uffi-1.4.12/src/os.x86f".
; Loading #p"/home/dave/.asdf-install-dir/site/resolver-0.2/packages.x86f".
; Loading #p"/home/dave/.asdf-install-dir/site/resolver-0.2/resolver.x86f".
 
Undefined foreign symbol: "res_query"
 
Restarts:
  0: [CONTINUE] Return NIL from load of
#p"/home/dave/.asdf-install-dir/site/resolver-0.2/resolver.x86f".
  1: [RETRY   ] Retry performing #<ASDF:LOAD-OP NIL {487D95AD}> on
                #<ASDF:CL-SOURCE-FILE "resolver" {48B9C3D5}>.
  2: [ACCEPT  ] Continue, treating #<ASDF:LOAD-OP NIL {487D95AD}> on
                #<ASDF:CL-SOURCE-FILE "resolver" {48B9C3D5}> as having been
                successful.
  3: [ABORT   ] Return to Top-Level.
 
Debug  (type H for help)
 
(KERNEL:UNDEFINED-FOREIGN-SYMBOL-ERROR-HANDLER "<error finding name>"
                                               #.(SYSTEM:INT-SAP #x3FFFE1B0)
                                               #<Alien (* #) at #x3FFFDE48>
                                               (14))
Source: Error finding source:
Error in function DEBUG::GET-FILE-TOP-LEVEL-FORM:  Source file no longer
exists:  target:code/interr.lisp.
0]


So, it looks like it isn't executing the (uffi:load-foreign-library ...)
form. Indeed, if I execute this by hand and then reload the resolver.x86f
file containing the (uffi:def-function ...) form, things work great. Also,
if I blow away the .x86f files and load the .lisp files by hand (asdf
always tries to compile them if they aren't already), things also work
great. So, somehow, in the compiled file, it isn't executing that when
loaded. I thought I would try to wrap the form in an EVAL-WHEN form, like
so:

(eval-when (:load-toplevel :compile-toplevel :execute)
  (uffi:load-foreign-library #p"/usr/lib/libresolv.so"
                             :supporting-libraries '("c")))

but that didn't work, either.

Does anybody have any hints?
-- 
Dave Roberts
·············@re-move.droberts.com
http://www.findinglisp.com/blog

From: Matthew Danish
Subject: Re: Trouble with compiled file using UFFI
Date: 
Message-ID: <20040430071055.GY25328@mapcar.org>
On Fri, Apr 30, 2004 at 06:13:12AM +0000, Dave Roberts wrote:
> So, it looks like it isn't executing the (uffi:load-foreign-library ...)

Indeed, it is a bug in CMUCL.  The work-around is to have the
LOAD-FOREIGN-LIBRARY form in a separate file from any uses of the
foreign library, and to compile/load it beforehand separately.

-- 
; Matthew Danish <·······@andrew.cmu.edu>
; OpenPGP public key: C24B6010 on keyring.debian.org
; Signed or encrypted mail welcome.
; "There is no dark side of the moon really; matter of fact, it's all dark."
From: Dave Roberts
Subject: Re: Trouble with compiled file using UFFI
Date: 
Message-ID: <NFnkc.2135$J71.374436@attbi_s03>
Matthew Danish wrote:

> On Fri, Apr 30, 2004 at 06:13:12AM +0000, Dave Roberts wrote:
>> So, it looks like it isn't executing the (uffi:load-foreign-library ...)
> 
> Indeed, it is a bug in CMUCL.  The work-around is to have the
> LOAD-FOREIGN-LIBRARY form in a separate file from any uses of the
> foreign library, and to compile/load it beforehand separately.
> 

Excellent! That worked like a charm. Thank you.

This brings up an interesting question, though... When, exactly, would I use
EVAL-WHEN, then? Seems obvious for things like reader macros, etc. Not sure
what else, though. Are there common, canonical uses?

-- 
Dave Roberts, ·············@re-move.droberts.com
Slowly but surely, the programming world is finding Lisp...
http://www.findinglisp.com/blog