Help with external plugins
David T. Lewis
lewis at mail.msen.com
Sat Feb 1 03:50:34 UTC 2003
On Wed, Jan 29, 2003 at 11:51:01PM -0500, Eddie Cottongim wrote:
> Here's an example of what I'm trying to do.
> For a C function residing in 'vorbisfile.dll' having the following
> int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes);
> I create this method in my plugin class (using the specification system, I
> assume thats the best way to go):
> primOvOpen: file oggVorbisFile: vf initial: initial long: ibytes
> |rcvr size |
> self primitive: 'primOvOpen'
> "unpleasant things"
> The following questions come up:
> The c-land things like FILE and the struct OggVorbis_File need to be
> allocated and released in c, right? I would guess that you do it in another
> primitive method (to ease the error handling), pass a pointer back to
> Smalltalk, and have an additional primitive method to release them when
> explicitly asked or the holding object gets GC'd.
The *vf would need to point to a data structure which you would allocate (or
declare static) in your plugin. If you are just trying to get things working,
you may want to start with a static allocation, and replace it with something
better once you have the primitive working. In any case, I would not recommend
handling your malloc() and free() from the Squeak side; just do it in the plugin.
(Speaking of malloc, I have the sense that it is a Bad Idea to use malloc any
more than absolutely necessary, on the theory that someone may someday redo
Squeak object memory in some way that does not mix well with plugins using the
malloc libraries. Just a hunch.)
As for the *f parameter, that is supposed to be a pointer to FILE, representing
a previously opened file. Therefore you do not have to allocate anything for it.
However, there's one glitch you will want to be aware of: although it would be
nice to open the file in Squeak and just pass the FileStream to your primitive,
it may not work nicely on various platforms. On Windows, the SQFile data structure
(in FilePlugin) has a member which is a Win32 HANDLE, whereas on other platforms
the same element of the data structure is a *FILE. There may be a way to make a
*FILE out of a HANDLE on Win32, but I have not figured it out yet. You may be
better off just passing the name of the file to your plugin, and doing the file
open in the plugin prior to calling ov_open().
I think this would lead you to a design in which your plugin would have a
primitiveOvOpen method which took the full file path name as its single
parameter, and answer some object representing the open Ogg Vorbis file
(could be an Integer which you would treat as a handle for the open file,
or perhaps a ByteArray containing the address of the OggVorbis_File data
structure -- but don't use the address as anything other than an opaque
handle). To close the file, you would have have a second primitive, say
primitiveOvClose, which would take one argument, the handle or ByteArray
which represents the open file. This primitive would take care of any
required cleanup, such as freeing the *vf data structure.
> Whats an 'oop', in the context of passing parameters to primitives?
An OOP is a 32 bit int. This is what gets passed to a primitive on the
stack. On the C side, it just looks like an int.
> How do I make the actual function call to the DLL ?
I'm not sure how DLLs work on Windows, but calling the function from
the primitive should just look like this:
result _ self cCode: 'ov_open(f, vf, NULL, 0)'.
More information about the Squeak-dev