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