[comp.sys.next] Lisp <-> Objective C

djlinse@phoenix.Princeton.EDU (Dennis Linse) (12/07/89)

An associate is trying to use the Allegro Common Lisp - Objective C
interface provided on the NeXT.  Nearly everything works fine, except
(you knew that was coming) when trying to access an objective-c class
defined in Lisp while in C.  This is confusing to describe.  Let me see
if an example helps.

The lisp looks something like
-------
(require :objc)
(require :foreign)
 
(use-package :excl)
(use-package :objc)
(use-package :appkit)
(use-package :foreign-functions)

(def-objc-class Expert (Object) ())
(def-objc-method (determineControllerCommands Expert :float) ()
 10.0)

(print-class Expert)

(load "SimulatorApp.o")
-----------

Included in SimulatorApp.m is a call to Expert (i.e. [Expert new]).
When this is loaded into Lisp, the class is created and printed out just
fine.  The loading of the .o file begins, but then fails with an error
something like "Symbol .objc_class_name_Expert undefined".  He was only
able to get this far by creating an .h file with an @interface to a
dummy Expert class.  I can see how this is incorrect, but I can't find
any other way to fix it.  What appears to be needed is an extern
declaration for the class, so that the Objective-C can be compiled
(without the dummy @interface, it won't even compile because Expert is
unknown).

Any pointers to the correct documentation, examples, or solutions would
be greatly appreciated.

Thanks!

Dennis Linse  (djlinse@phoenix.princeton.edu)

ed@DTG.COM (Edward Jung) (12/09/89)

In article <11996@phoenix.Princeton.EDU>, djlinse@phoenix (Dennis Linse) writes:
>
>An associate is trying to use the Allegro Common Lisp - Objective C
>interface provided on the NeXT.  Nearly everything works fine, except
>(you knew that was coming) when trying to access an objective-c class
[code deleted]
>
>Included in SimulatorApp.m is a call to Expert (i.e. [Expert new]).
>When this is loaded into Lisp, the class is created and printed out just
>fine.  The loading of the .o file begins, but then fails with an error
>something like "Symbol .objc_class_name_Expert undefined".  He was only
>able to get this far by creating an .h file with an @interface to a
>dummy Expert class.  I can see how this is incorrect, but I can't find
>any other way to fix it.  What appears to be needed is an extern
>declaration for the class, so that the Objective-C can be compiled
>(without the dummy @interface, it won't even compile because Expert is
>unknown).

The "[Expert new]" is compiled into code that looks for an Objective-C
symbol for Expert, that is, ".objc_class_name_Expert".  Since that is
not in the image, the link fails.

You should use the following instead:

	#import <objc/objc.h>

	[objc_getClass("Expert") new];

Alternatively, you can "cache" the class (factory) object:

	id Expert;

	Expert = objc_getClass("Expert");

	my_expert = [Expert new];

Both examples insure that the symbol is extracted from the run-time
image rather than the compiled (static) information.

-- 
Edward Jung                             The Deep Thought Group, L.P.
BIX: ejung                                      3400 Swede Hill Road
NeXT or UNIX mail                                Clinton, WA.  98236
        UUCP: uunet!dtgcube!ed          Internet: ed@dtg.com

cox@Franz.COM (Charles A. Cox) (12/11/89)

In article <1989Dec8.220555.3912@uunet!dtgcube> ed@DTG.COM (Edward Jung) writes:
   In article <11996@phoenix.Princeton.EDU>, djlinse@phoenix (Dennis Linse) writes:
	[ . . . ]
   >Included in SimulatorApp.m is a call to Expert (i.e. [Expert new]).
   >When this is loaded into Lisp, the class is created and printed out just
   >fine.  The loading of the .o file begins, but then fails with an error
   >something like "Symbol .objc_class_name_Expert undefined".  He was only
   >able to get this far by creating an .h file with an @interface to a
   >dummy Expert class.  I can see how this is incorrect, but I can't find
   >any other way to fix it.  What appears to be needed is an extern
   >declaration for the class, so that the Objective-C can be compiled
   >(without the dummy @interface, it won't even compile because Expert is
   >unknown).

   The "[Expert new]" is compiled into code that looks for an Objective-C
   symbol for Expert, that is, ".objc_class_name_Expert".  Since that is
   not in the image, the link fails.

This analysis is correct.  The thing you want to do is get the class
definition loaded into the lisp's process.  If the Expert class is in
file.o, then if you load file.o into the lisp before the loading of
your .o file, you should be okay.  If the Expert class is in a library
lib.a, then you can load it by using the :unreferenced-lib-names
keyword of the load function:


 (load "lib.a" :unreferenced-lib-names '(".objc_class_name_Expert"))

I have an example of a complete Lisp program which plays scorefiles
that shows how to use this :unreferenced-lib-names feature to load in
classes from the musickit library.  The loading is done this way
because the musickit classes aren't already part of the lisp.  Since I
didn't manage to finish the example before the NeXT 1.0 freeze date,
the program didn't make it into the examples/ subdirectory of the lisp
distribution directory.  However, if anyone would like a copy of it
(it is 419 lines), send me your email address and I'll mail it to you.

	Charley
--
---
Charles A. Cox, Franz Inc.        1995 University Avenue, Suite 275
Internet: cox@franz.com           Berkeley, CA  94704
uucp:     uunet!franz!cox         Phone: (415) 548-3600    FAX: (415) 548-8253