Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!ucbvax!decwrl!sun!pitstop!sundc!seismo!uunet!mcvax!unido!laura!atoenne From: atoenne@laura.UUCP (Andreas Toenne) Newsgroups: comp.lang.smalltalk Subject: Re: Interface st-80 and C. Message-ID: <1109@laura.UUCP> Date: 18 Feb 89 14:44:33 GMT References: <1330@iesd.uucp> Reply-To: atoenne@laura.UUCP (Andreas Toenne) Organization: University of Dortmund, W-Germany Lines: 82 In article <1330@iesd.uucp> genbrug@iesd.dk (Dat hovedfag genbrug) writes: >In my project I need to be able to, from the smalltalk-80 system, to call >some C functions, but I don't know how to do it (I have been reading >"The Smalltalk-80 Programming Environment" chapter 12 about the >subject but without succes) This is the idea how to do user primitives: 1. Smalltalk part: User primitives (once they are announced) may be invoked like ordinary primitives. They have a negative primitive number however. If you invoke a primitive that is not existant, then the primitive fails. The arguments to the smalltalk method invoking this primitive are taken as the arguments for the primitive C function. The primitive call must be the FIRST smalltalk statement in this method. Example: funnyNoopMethod: myFirstArg with: mySecondArg "Do nothing. The C primitive assumes that myFirstArg is a byte array and mySecondArg a boolean value" "This code is invoked, if the C primitive fails" ^ self error: 'Dummy you :-)' 2. C part: First you have to announce the new primtive to smalltalk. Do this with a redeclaration of UPinstall(). UPinstall is invoked at the very start of Smalltalk. It should contain UPaddPrimitive calls for each new primitive (ie. for the C function). It may return a string which is printed to the screen after the installation. UPaddPrimitive gets the three arguments primitive number, function pointer and number of arguments. All this arguments are assumed to be of type LONG (32 bit). The primitive number must be negative. Example: #include "userprim.h" UPinstall() { UPaddPrimitive(-1, myNoopFunction, 2); /* int=long assumed */ return("Noop installed"); } Next you should write the C function for this new primitive. This is the idea: - Smalltalk objects and C data structures are strictly seperated. You have to do conversion between this two worlds. No pointer sharing is possible (I consider this a bad design). Object pointers kept between two invocation of the primitives are made INVALID! - The C function for the primitive gets at least the OBJECT POINTER of type upHandle to the receiving object. Every argument given to the Smalltalk method is added to the arguments. - Before doing anythiny else, call UPbegin with this object pointer for the receiver and the number of argument. Example: upHandle myNoopFunction(RR, myFirstArg, mySecondArg) upHandle RR, myFirstArg, mySecondArg; { UPbegin(RR, 2); "Lets check the arguments for correct types" UPmustBeByteArray(myFirstArg); UPmustBeBoolean(mySecondArg); "you could now insert your code" UPreturnNil(); } Hope this helps. Let me know if you have some specific questions. Andreas atoenne@unido.uucp