3. Design the C Interface
The next step is to design the interface for the C-side of the primitive, and to write a C function prototype for it. For the Siren VM C header file, I did:int sqReadMIIPacket(int MIDIpacket, int dataBuffer); // Read input into a MIDI packet. (prim. 614) // 'MIDIpacket' is interpreted as (MIDIPacket *) and is // written into with the time-stamp, flags, and length. // 'dataBuffer' is interpreted as (unsigned char *) and // gets the MIDI message data. // Answer the number of data bytes in the packet.
Note that all arguments are passed as ints; you can cast them into 'whatever' at will in the C code (see below). (This is yet another reason to write really good comments in your interfaces.)
Most of my primitives return integers (negative values for common error conditions, I apologize, I just programmed in C for too long in my youth) and fail only in extreme situations. This is a personal preference--I tend to pass the error return values up to higher levels of code to handle. Other designers might always want to have a failure handler right in the method that called the prim--see the discussion below. It would be easier if Squeak had well-integrated exception handling and raised a system exception on primitive failure so that the calling method could decide whether to use the primitive method's failure code or not.