Strategies to prevent class name clashes
-
Hi,
I'm just porting an open source UI toolkit to Cocoa. This toolkit is
mainly used in plug-ins by many different people. So it's more than
likely that two or more plug-ins get loaded into the same process.
It's also very common that the people who uses the toolkit modify the
source. This all worked in C++ because all bundles were loaded into
different name spaces. With Objective-C this is no longer the case. I
already got a problem while porting that two plug-ins that uses the
toolkit were compiled at different times with different code. But as a
nature of Objective-C it only loaded the classes once. I'm looking now
for a way to prevent this. Does anyone have any idea how to best deal
with this ?
thanks
arne -
On 15 Feb 2008, at 10:09, Arne Scheffler wrote:
> Hi,
> I'm just porting an open source UI toolkit to Cocoa. This toolkit is
> mainly used in plug-ins by many different people. So it's more than
> likely that two or more plug-ins get loaded into the same process.
> It's also very common that the people who uses the toolkit modify
> the source. This all worked in C++ because all bundles were loaded
> into different name spaces. With Objective-C this is no longer the
> case. I already got a problem while porting that two plug-ins that
> uses the toolkit were compiled at different times with different
> code. But as a nature of Objective-C it only loaded the classes
> once. I'm looking now for a way to prevent this. Does anyone have
> any idea how to best deal with this ?
Use class name prefixes as a simple namespace substitute. That's why
Cocoa class names are prefixed with NS ( see "Prefixes" in http://www.stepwise.com/Articles/Technical/2002-10-13.01.html
).
--Lieven -
On Feb 15, 2008, at 10:42 AM, Lieven Dekeyser wrote:
>
> On 15 Feb 2008, at 10:09, Arne Scheffler wrote:
>
>> Hi,
>> I'm just porting an open source UI toolkit to Cocoa. This toolkit
>> is mainly used in plug-ins by many different people. So it's more
>> than likely that two or more plug-ins get loaded into the same
>> process. It's also very common that the people who uses the toolkit
>> modify the source. This all worked in C++ because all bundles were
>> loaded into different name spaces. With Objective-C this is no
>> longer the case. I already got a problem while porting that two
>> plug-ins that uses the toolkit were compiled at different times
>> with different code. But as a nature of Objective-C it only loaded
>> the classes once. I'm looking now for a way to prevent this. Does
>> anyone have any idea how to best deal with this ?
>
> Use class name prefixes as a simple namespace substitute. That's why
> Cocoa class names are prefixed with NS ( see "Prefixes" in http://www.stepwise.com/Articles/Technical/2002-10-13.01.html
> ).
So, you want to advise me that every user of the toolkit should edit
the objective-c class names ?
Programmers are lazy. They simply forget to do this and the result
will be that the hosting app will eventually crash. So this is not a
solution for me.
thanks anyway
arne -
Arne Scheffler wrote:
> I already got a problem while porting that two plug-ins that uses
> the toolkit were compiled at different times with different code.
> But as a nature of Objective-C it only loaded the classes once. I'm
> looking now for a way to prevent this. Does anyone have any idea how
> to best deal with this ?
Do you have to include the toolkit in the plugins? There are ways
how one could have the plugin toolkit in the host application, or in a
framework, and have all the plugins dynamically link it in. If you
keep the size of the instance variable area constant (e.g. by using a
pointer to a struct to hold all ivars, or a dictionary if performance
is not an issue), they can even subclass your toolkit classes and
modify their behaviour that way. That would be much cleaner and is
what OOP was actually designed to allow. At least you would no longer
have to worry about namespace collisions among your toolkit classes.
On 15.02.2008, at 10:42, Lieven Dekeyser wrote:
> Use class name prefixes as a simple namespace substitute. That's why
> Cocoa class names are prefixed with NS ( see "Prefixes" in http://www.stepwise.com/Articles/Technical/2002-10-13.01.html
> ).
Well, nobody wants to edit the whole framework to have new prefixes,
but this is a common convention in Cocoa and will thus automatically
be used for the plugin developers' classes. For the framework, you
could achieve the same if you #define your toolkit's class names to
something unique for each build. You could e.g. have a shell script
build phase as the first phase in your project that generates a header
file that generates unique names for your classes, like:
#define ASToolkitWindow ASToolkit_JeffsPluginProject_Window
etc., maybe even append some other unique data to the names (bundle
identifier from the Info.plist?). Then include that header in all your
files and they'll "rename" the framework, and each plugin will get
their own copy. I did the same for some utility classes when I wrote
Cocoa Xcmds for SuperCard, though since we were talking only two
classes and three projects, I wrote the header manually there. Of
course, dynamically renaming classes this way means anyone trying to
use NSClassFromString() on such a class will fail, which includes
specifying one of these classes as the main class of your bundle.
Of course, with both approaches, the user's classes still have to be
uniquely named. If two guys have a PluginDelegate class, it'll still
break. A venue to investigate would probably be NSBundle - I think it
can give you a list of all classes in a bundle. So, you could probably
get a list of all classes, look at the bundle's class list (not sure
whether that would require loading it, though), and if any of the
names are the same, quarantine the newly-loaded plugin and bail,
telling the user which plugins collided, and telling them how to
exchange the one colliding plugin for the other, if the one you threw
out was more important to them than the one you had already loaded.
Cheers,
-- Uli Kusterer
"The Witnesses of TeachText are everywhere..."
http://www.zathras.de -
Hi Uli,
the toolkit in question is VSTGUI. It's a C++ cross-platform UI
library. It is statically linked into every plug-in. Mostly the users
of it won't use Objective-C by them self.
The problem I did face was that I have an ivar which is a C++ class of
the lib. And when I used this ivar and the C++ object had a different
layout than at build time it crashed. Here's an outline of what I mean :
class CFrame
{
public:
//...
};
@interface VSTGUI_NSView : NSView {
CFrame* _frame;
}
- (id) initWithCFrame: (CFrame*) frame;
@end
It crashed inside initWithCFrame because CFrame did change because one
of the plug-in used a newer version of the lib.
It seems like I'm out of luck if I'm going this route.
After thinking about it a while I think I need to write C functions
which will interact between the C++ class and the Objective-C class.
After all this Cocoa change is a headache for plug-ins.
thanks
arne
On Feb 15, 2008, at 11:43 AM, Uli Kusterer wrote:
> Arne Scheffler wrote:
>> I already got a problem while porting that two plug-ins that uses
>> the toolkit were compiled at different times with different code.
>> But as a nature of Objective-C it only loaded the classes once. I'm
>> looking now for a way to prevent this. Does anyone have any idea
>> how to best deal with this ?
>
> Do you have to include the toolkit in the plugins? There are ways
> how one could have the plugin toolkit in the host application, or in
> a framework, and have all the plugins dynamically link it in. If you
> keep the size of the instance variable area constant (e.g. by using
> a pointer to a struct to hold all ivars, or a dictionary if
> performance is not an issue), they can even subclass your toolkit
> classes and modify their behaviour that way. That would be much
> cleaner and is what OOP was actually designed to allow. At least you
> would no longer have to worry about namespace collisions among your
> toolkit classes.
>
> On 15.02.2008, at 10:42, Lieven Dekeyser wrote:
>> Use class name prefixes as a simple namespace substitute. That's
>> why Cocoa class names are prefixed with NS ( see "Prefixes" in http://www.stepwise.com/Articles/Technical/2002-10-13.01.html
>> ).
>
>
> Well, nobody wants to edit the whole framework to have new prefixes,
> but this is a common convention in Cocoa and will thus automatically
> be used for the plugin developers' classes. For the framework, you
> could achieve the same if you #define your toolkit's class names to
> something unique for each build. You could e.g. have a shell script
> build phase as the first phase in your project that generates a
> header file that generates unique names for your classes, like:
>
> #define ASToolkitWindow ASToolkit_JeffsPluginProject_Window
>
> etc., maybe even append some other unique data to the names (bundle
> identifier from the Info.plist?). Then include that header in all
> your files and they'll "rename" the framework, and each plugin will
> get their own copy. I did the same for some utility classes when I
> wrote Cocoa Xcmds for SuperCard, though since we were talking only
> two classes and three projects, I wrote the header manually there.
> Of course, dynamically renaming classes this way means anyone trying
> to use NSClassFromString() on such a class will fail, which includes
> specifying one of these classes as the main class of your bundle.
>
> Of course, with both approaches, the user's classes still have to be
> uniquely named. If two guys have a PluginDelegate class, it'll still
> break. A venue to investigate would probably be NSBundle - I think
> it can give you a list of all classes in a bundle. So, you could
> probably get a list of all classes, look at the bundle's class list
> (not sure whether that would require loading it, though), and if any
> of the names are the same, quarantine the newly-loaded plugin and
> bail, telling the user which plugins collided, and telling them how
> to exchange the one colliding plugin for the other, if the one you
> threw out was more important to them than the one you had already
> loaded.
>
> Cheers,
> -- Uli Kusterer
> "The Witnesses of TeachText are everywhere..."
> http://www.zathras.de
>
>
>
>
>
-
On 15.02.2008, at 12:42, Arne Scheffler wrote:
> the toolkit in question is VSTGUI. It's a C++ cross-platform UI
> library. It is statically linked into every plug-in. Mostly the
> users of it won't use Objective-C by them self.
> The problem I did face was that I have an ivar which is a C++ class
> of the lib. And when I used this ivar and the C++ object had a
> different layout than at build time it crashed. Here's an outline of
> what I mean :
You simply were lucky.
The OS X dyld loader not only loads Cocoa classes just one but also
uses just the very first instance of any given symbol.
That means if one plugin loads the audio equivalent af libTiff2.4 and
another the equivalent of libTiff2.6, they are likely to crash.
Or an plugin using boost 1.3.2 will affect the plugin with a fixed
boost version 1.3.3. And it's the reason why an plugin cannot use the
debug STL variant in an host using the nondebug STL implementation.
Options are either to
- use a common framework (+versioning) for the implementation (less
footprint)
or
- educate users to switch the symbol visibility for each and every
library symbol to private, meaning they will not be shared (more mem
footprint)
- or create an e.g. preprocessor based class naming scheme where e.g.
VSTUIClass will be replaced by VSTUIClass2_0
(once again, less footprint as all plugins share a 2.0 implementation,
only the ones using 1.9 will load another implementation..)
Especially for audio I'd go with a potentially shared implementation
as additional code might mean VM usage exceeding physical memory, i.e.
swapping...
Regards,
Tom_E -
On Feb 15, 2008, at 1:04 PM, Thomas Engelmeier wrote:
>
> On 15.02.2008, at 12:42, Arne Scheffler wrote:
>
>> the toolkit in question is VSTGUI. It's a C++ cross-platform UI
>> library. It is statically linked into every plug-in. Mostly the
>> users of it won't use Objective-C by them self.
>> The problem I did face was that I have an ivar which is a C++ class
>> of the lib. And when I used this ivar and the C++ object had a
>> different layout than at build time it crashed. Here's an outline
>> of what I mean :
>
> You simply were lucky.
> The OS X dyld loader not only loads Cocoa classes just one but also
> uses just the very first instance of any given symbol.
> That means if one plugin loads the audio equivalent af libTiff2.4
> and another the equivalent of libTiff2.6, they are likely to crash.
> Or an plugin using boost 1.3.2 will affect the plugin with a fixed
> boost version 1.3.3. And it's the reason why an plugin cannot use
> the debug STL variant in an host using the nondebug STL
> implementation.
>
No, dyld as of Mac OS X 10.2 supports two-level namespaces. Otherwise
AudioUnits and VST plug-ins wouldn't work on Mac OS X. As an example
every VST plug-in just exports one C function and yet I haven't heard
of a host only be able to load one VST plug-in.
I think what you mean is if some one tries to load a dylib and there's
already a dylib with the same name in the process, than you're right
it only loads the first one.
I'm talking about a bundle which will be loaded via
CFBundleLoadExecutable.
At present, when not using Objective-C, if the dyld maps two different
bundles into the process the symbols will be in separate namespaces so
that there could be the same symbol twice and the names would not
clash. Plug-in A will always call the right symbol even if plug-in B
has a symbol with the same name.
With Objective-C now this won't work anymore.
> Options are either to
> - use a common framework (+versioning) for the implementation (less
> footprint)
How does framework versioning work for Cocoa ? If one plug-in got
compiled with say version 1 and another got compiled with version 2.
Will they both work ? How is that possible as Objective-C only allows
one class with the same name ?
thanks
arne -
On 15.02.2008, at 13:35, Arne Scheffler wrote:
> No, dyld as of Mac OS X 10.2 supports two-level namespaces.
> Otherwise AudioUnits and VST plug-ins wouldn't work on Mac OS X. As
> an example every VST plug-in just exports one C function and yet I
> haven't heard of a host only be able to load one VST plug-in.
OK, with two level namespaces that is partially resolved.
> I think what you mean is if some one tries to load a dylib and
> there's already a dylib with the same name in the process, than
> you're right it only loads the first one.
IIRC the symbol resolution is applicable to referenced symbols, but
not to bundle entry points.
> With Objective-C now this won't work anymore.
Certainly not. If I understood it correctly, objc_lookUpClass does not
know the concept of namespaces, and classes get added at bundle load
time to the internal class lookup table.
[[foo alloc] init];
is AFAIK (not sure 'bout the SEL lookup..) equivalent to
id aClass = objc_getClass( "foo" ); // NO NAMESPACES HERE - plain
ASCII class name!!!!
id anObject = objc_msgSend( aClass, sel_getUid( "alloc") );
objc_msgSend( anObject, sel_getUid( "init") );
> How does framework versioning work for Cocoa ? If one plug-in got
> compiled with say version 1 and another got compiled with version 2.
> Will they both work ?
You´re right: it won't work.
> How is that possible as Objective-C only allows one class with the
> same name ?
>
See above. The Objective-C runtime reference is pretty enlightening by
revealing some implementation details, the "Code loading programming
topics for Cocoa" contains some more clarifications...
Regards,
Tom_E -
On Feb 15, 2008, at 5:42 AM, Arne Scheffler wrote:
> Hi Uli,
> the toolkit in question is VSTGUI. It's a C++ cross-platform UI
> library. It is statically linked into every plug-in. Mostly the
> users of it won't use Objective-C by them self.
> The problem I did face was that I have an ivar which is a C++ class
> of the lib. And when I used this ivar and the C++ object had a
> different layout than at build time it crashed. Here's an outline of
> what I mean :
>
This is the class "Fragile Base Class" problem that plagues C++.
There are a few strategies to avoid this (search the web for ideas),
but they often get more complicated than is practical to implement -
re-implementing SOM is not something that you'd really want to do.
>
> After thinking about it a while I think I need to write C functions
> which will interact between the C++ class and the Objective-C class.
> After all this Cocoa change is a headache for plug-ins.
>
This problem is a C++ problem - not that Objective-C doesn't have
that problem, but it is much rarer (in Objective C you can add method
to a base class without breaking things, which you can't safely do in C
++ since that alters the vtable layout, though adding ivars can also
break things). Objective-C 2.0 also addresses this problem, but I'm
guessing you can't require that.
There are also work-arounds for the Objective-C plugin namespace
collisions, but those require a fair amount of experience with both
the runtime and the mach-o file format. The basic strategy is to take
the binary in the plugin, make a copy, and edit the names of the
classes in the file to avoid collisions (walk the sections, find the
objective-c information, walk the modules to find the class
definitions, and then find the corresponding class names in the
strings table, and edit the strings table accordingly - this, of
course, is for Objective-C 1.0). Even this approach isn't foolproof,
since there may be a collision between a class in the plugin that you
rename that is also referred to in a nib file (which will then get the
non-plugin version of that class).
The safest solution is to launch your plugins in their own executable
space (using a simple host "nub") and use DO to communicate between
the plugin and the host. This isn't as fast, but it is much safer and
reliable (since you can even have a plugin crash and not take down the
host app).
At the very least, you'll want to review:
<http://developer.apple.com/documentation/Cocoa/Conceptual/LoadingCode/Conce
pts/Plugins.html>
and
<http://developer.apple.com/documentation/Cocoa/Conceptual/LoadingCode/Tasks
/UsingPlugins.html>
Glenn Andreas <gandreas...>
<http://www.gandreas.com/> wicked fun!
quadrium | prime : build, mutate, evolve, animate : the next
generation of fractal art -
On 2008-02-16, at 01:43, glenn andreas wrote:
> This problem is a C++ problem - not that Objective-C doesn't have
> that problem, but it is much rarer (in Objective C you can add
> method to a base class without breaking things, which you can't
> safely do in C++ since that alters the vtable layout, though adding
> ivars can also break things). Objective-C 2.0 also addresses this
> problem, but I'm guessing you can't require that.
For completeness, Objective-C 2.0 on the 64 bit runtime avoids the
fragile base class problem, but Objective-C 2.0 on 32 bit is the same
as before.
Jonathon Mah
<me...> -
On Feb 15, 2008, at 4:35 AM, Arne Scheffler wrote:
> How does framework versioning work for Cocoa ? If one plug-in got
> compiled with say version 1 and another got compiled with version 2.
> Will they both work ? How is that possible as Objective-C only
> allows one class with the same name ?
Framework versioning won't help in this case.
Objective-C has a flat namespace for all classes. It is one of the
handful of penalties resulting from its focus upon simplicity.
In general, it is considered odd that a set of plugins would
statically link in the shared UI driver bits. Doing so increases
memory footprint and can be exceedingly problematic unless the
functionality within each plugin is maintained in total isolation.
b.bum -
On Feb 15, 2008, at 11:53 AM, Bill Bumgarner wrote:
>
> In general, it is considered odd that a set of plugins would
> statically link in the shared UI driver bits. Doing so increases
> memory footprint and can be exceedingly problematic unless the
> functionality within each plugin is maintained in total isolation.
It is -- the functionality within each plugin is maintained by
thousands of developers world-wide. Arne is trying to develop a Cocoa
compatibility layer for a C++ UI framework, that I expect would not
require any changes to the C++ side of the client code for those
thousands of plugins. I am guessing that this is being driven by the
fact that 64-bit Carbon was dropped and that there is a desire, long
term, to support 64-bit in VST hosts...
In the audio world, the plugins have generally carried around
statically linked versions of their glue and UI code. It hasn't been
exceedingly problematic until we start to factor in the need to
integrate with Cocoa.
Best regards,
B.J. Buchalter
Metric Halo
http://www.mhlabs.com -
Thanks all, for your comments and ideas how to solve this issue.
After all the only workable solution to this problem is to create the
Objective-C classes at runtime.
As B.J. already said this is only glue code which only consists of 5
Objective-C classes. But even with this few classes it's much work to
convert my already written code to this mimic. I can only hope that no
one else need to do this kind of ugly work. But for the ones who need,
look at the "Objective-C 2.0 Runtime Reference" or at <objc/runtime.h>
file.
arne -
On 15 Feb '08, at 3:42 AM, Arne Scheffler wrote:
> the toolkit in question is VSTGUI. It's a C++ cross-platform UI
> library. It is statically linked into every plug-in. Mostly the
> users of it won't use Objective-C by them self.
> The problem I did face was that I have an ivar which is a C++ class
> of the lib. And when I used this ivar and the C++ object had a
> different layout than at build time it crashed.
I'm confused — is this a problem of collisions between C++ classes or
Obj-C classes?
If the C++ code is statically linked into each plugin, then it can't
conflict between multiple plugins. Each one will be directly calling
its own copy of the code, even if the C++ classnames and namespaces
are the same.
Objective-C classes _will_ conflict between multiple plugins, if they
have the same name. So what you have to do is make sure that every
plugin that statically links shared Obj-C code renames the classes
with unique prefixes. Basically, any time you write an Obj-C bundle or
framework, all the classes in it need to have a unique prefix, whether
or not you wrote those classes yourself.
It sounds like what's happening to you is that some of your classes
load out of your bundle and some get loaded from another plugin, and
these mismatched classes are passing C++ object pointers between
themselves. So when code from one plugin allocates a C++ object (with
one version of the C++ code), and then code from a different plugin
receives a pointer to that object and tries to operate on it using a
different version of the C++ code, you go boom.
But that's not a C++ specific problem. As soon as you have parts of
different versions of a library loaded and calling into each other,
there will be trouble. I've had this happen with Obj-C and pure C code
as well. You have to uniquify your Obj-C class names to avoid this.
—Jens -
On Feb 16, 2008, at 5:42 PM, Jens Alfke wrote:
>
> On 15 Feb '08, at 3:42 AM, Arne Scheffler wrote:
>
>> the toolkit in question is VSTGUI. It's a C++ cross-platform UI
>> library. It is statically linked into every plug-in. Mostly the
>> users of it won't use Objective-C by them self.
>> The problem I did face was that I have an ivar which is a C++ class
>> of the lib. And when I used this ivar and the C++ object had a
>> different layout than at build time it crashed.
>
> I'm confused — is this a problem of collisions between C++ classes
> or Obj-C classes?
>
> If the C++ code is statically linked into each plugin, then it can't
> conflict between multiple plugins. Each one will be directly calling
> its own copy of the code, even if the C++ classnames and namespaces
> are the same.
>
> Objective-C classes _will_ conflict between multiple plugins, if
> they have the same name. So what you have to do is make sure that
> every plugin that statically links shared Obj-C code renames the
> classes with unique prefixes. Basically, any time you write an Obj-C
> bundle or framework, all the classes in it need to have a unique
> prefix, whether or not you wrote those classes yourself.
>
> It sounds like what's happening to you is that some of your classes
> load out of your bundle and some get loaded from another plugin, and
> these mismatched classes are passing C++ object pointers between
> themselves. So when code from one plugin allocates a C++ object
> (with one version of the C++ code), and then code from a different
> plugin receives a pointer to that object and tries to operate on it
> using a different version of the C++ code, you go boom.
>
> But that's not a C++ specific problem. As soon as you have parts of
> different versions of a library loaded and calling into each other,
> there will be trouble. I've had this happen with Obj-C and pure C
> code as well. You have to uniquify your Obj-C class names to avoid
> this.
>
The problem is Objective-C. As written earlier this toolkit is used by
more than a hundred different plug-ins from different manufactures who
all may add some patches by their own to the C++ classes. The toolkit
consists of a few files which will be added to the xcode project of
the plug-in. So there's no shared library the plug-in links to. This
toolkit is also cross platform, currently working on Windows and Mac
OS X (Carbon). There were ports for classic Mac OS, BeOS and Motif in
the past.
So there are a few wrapper classes to wrap platform specifics. For
Cocoa I needed to make a subclass of NSView. The implementation of
this class needs to call some of the C++ classes. If there's another
plug-in loaded which also uses the toolkit it's likely that the
objective-c class is using the wrong vtable of some of the C++ classes
when they were modified.
Apple already knows about this problem since they removed HIToolbox
from the 64-bit version of Mac OS X. And they acknowledged it.
After digging deep into the runtime of objective-c I think it should
be fairly easy to support some kind of two level namespaces for it. I
hope that they will add something like that in the next major version
of os x. But for now I needed a working solution, which I found by
creating the objective-c classes at runtime.
arne -
On Feb 16, 2008, at 10:14 AM, Arne Scheffler wrote:
> After digging deep into the runtime of objective-c I think it should
> be fairly easy to support some kind of two level namespaces for it.
> I hope that they will add something like that in the next major
> version of os x. But for now I needed a working solution, which I
> found by creating the objective-c classes at runtime.
If you haven't already, please file bugs documenting your explicit
needs. Send me the bug # directly, please, and I'll dupe it to the
oldest "i can haz namespaces, pleez" bug in the system after capturing
your specific needs in said master bug.
You are correct in that it isn't hard to dynamically generate the
needed classes. The runtime provides all the API necessary for doing
so.
If possible, one pattern that has been successfully used that
minimizes metadata issues is to:
- create an abstract superclass that contains stub implementations of
methods with the argumentation you'll need (i.e. "method that returns
int and takes two floats, method that returns int and takes three
floats, etc...")
- implement C functions in your plugin(s) that have the correct method-
like argumentation and call through to your C++ code
int foo(AbstractClass *self, SEL _cmd, float a, float b) { .. call C+
+ ..; }
int foo(AbstractClass *self, SEL _cmd, float a, float b, float c) { ..
call C++ ..; }
- on plugin load, dynamically generate a subclass of your abstract
class and plugin the C functions as IMPs. By declaring the various
methods on the AbstractClass, you can grab the method signatures from
that class instead of having to manually generate those awful type
signatures (i@:ff, for example -- and that may not even be write).
b.bum -
On Feb 16, 2008, at 12:18 AM, Arne Scheffler wrote:
> After all the only workable solution to this problem is to create
> the Objective-C classes at runtime.
Just have your application just contain an embedded framework against
which plug-ins must link.
Then the Objective-C classes that would normally be replicated in
every plug-in can be put in the framework instead. You won't have
Objective-C class name conflicts in the plug-ins then, and you will
also be able to roll out changes to the Objective-C classes very easily.
Providing a "toolkit" which consists of source code to link into each
plug-in sounds like a maintenance nightmare. How would you deal with
code linked against version 1.1 of the toolkit trying to load into
version 3.0 of the application? These are the kinds of problems
frameworks were designed to solve.
-- Chris



