Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
Discussion Groups
General
GeneralPortable MacsHardwareNetworking
Applications
Mac ApplicationsEudoraFirefox / MozillaInternet ExplorerOutlook ExpressMS OfficeEntourageExcelPowerPointWordVirtual PCMedia PlayerOther MS Products
Programming
Mac ProgrammingCodeWarriorPerl
Country Specific
Australian Mac GroupUK Mac Group

Mac Forum / Programming / Mac Programming / December 2006



Tip: Looking for answers? Try searching our database.

Plugin architecture and class names

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
gebiet@gmail.com - 27 Dec 2006 11:47 GMT
Hello, planet :-)

 I have application with some plugins (A and B). Plugins are bundles
with single principal class. Two of plugins uses class with class
(static) method (ScriptLauncher +Launch:).
 Problem: static method of plugin A call both from plugins A and B!
 What have I do to make this classes invisible from other plugin?

Sorry for my english and thanks for answer.
Michael Ash - 27 Dec 2006 16:20 GMT
> Hello, planet :-)
>
[quoted text clipped - 3 lines]
>  Problem: static method of plugin A call both from plugins A and B!
>  What have I do to make this classes invisible from other plugin?

You have to give them different names. I assume this is Objective-C from
what you've said, although it would be helpful for you to state this
explicitly in the future. In Objective-C it is illegal to have two classes
with the same name in the same program. The class namespace is global,
even though you're loading the two classes from different plugins, and so
the names conflict.

Signature

Michael Ash
Rogue Amoeba Software

gebiet@gmail.com - 28 Dec 2006 09:19 GMT
> You have to give them different names. I assume this is Objective-C from
> what you've said, although it would be helpful for you to state this
> explicitly in the future. In Objective-C it is illegal to have two classes
> with the same name in the same program. The class namespace is global,
> even though you're loading the two classes from different plugins, and so
> the names conflict.

Thanks, Michael,

It is developers' hell, as I understood. Third-party plugin developers
have to arrange between himself about names of internal classes.
Michael Ash - 28 Dec 2006 17:15 GMT
>> You have to give them different names. I assume this is Objective-C from
>> what you've said, although it would be helpful for you to state this
[quoted text clipped - 7 lines]
> It is developers' hell, as I understood. Third-party plugin developers
> have to arrange between himself about names of internal classes.

"Hell" is overstating it. Making sure your names don't clash isn't really
hard.

You just need to prefix your class names with something unique. The
something depends on how paranoid you want to be. For most cases, choosing
something related to the name of the plugin should suffice. If your plugin
is called BreadMaker, then name your classes BMController, BMWindow, etc.
For extra paranoia (Apple recommends this for screensavers), you can use a
bundle ID sort of prefix, like ComBreadCompanyBreadMakerController. This
is a bit unwieldy, though.

Signature

Michael Ash
Rogue Amoeba Software

David Phillip Oster - 29 Dec 2006 04:23 GMT
> For extra paranoia (Apple recommends this for screensavers), you can use a
> bundle ID sort of prefix, like ComBreadCompanyBreadMakerController. This
> is a bit unwieldy, though.

but at the top of each .h file, you just need to add a single line, for
example,

#define Controller ComBreadCompanyBreadMakerController

then recompile. Now your source code uses short names, but the linker
uses long names. Done.
David Phillip Oster - 29 Dec 2006 04:31 GMT
> > For extra paranoia (Apple recommends this for screensavers), you can use a
> > bundle ID sort of prefix, like ComBreadCompanyBreadMakerController. This
[quoted text clipped - 7 lines]
> then recompile. Now your source code uses short names, but the linker
> uses long names. Done.

But the problem comes back when plugins themselves have plugins, and
plugin A needs version 1.0 of plugin C, while plugin B needs version 2.0
of plugin C, and, naturally, both version of plugin C and version 2 of
plugin C export the same symbols.  

In Windows XP, you can put a Manifest.xml file in your plugin or DLL.
Your Manifest.xml file states exactly what version of what other
components you require, and the Windows XP loader manages connecting
your plugin to the correct versions, without them stomping on each
other. But Macintosh OS X has too few programs and is too immature to
have had the DLL-Hell problem that required Microsoft to implement this
fix, so we Mac programmers are out of luck.

I've seen symbol mangling programs on Mac that edit compiled code, and
copies of dynamically linked frameworks, to get around this problem.

Possibly there are loader options I don't know about.
Michael Ash - 29 Dec 2006 17:21 GMT
>> > For extra paranoia (Apple recommends this for screensavers), you can use a
>> > bundle ID sort of prefix, like ComBreadCompanyBreadMakerController. This
[quoted text clipped - 7 lines]
>> then recompile. Now your source code uses short names, but the linker
>> uses long names. Done.

Not quite done. You have to make sure that any external references to your
classes uses the long name. For example, Principal Class in your
Info.plist, class names in your nib. This isn't a huge problem but
particularly since IB will not see the #define and will pick up the short
name when you parse the header, you have to be careful. Also things like
NSClassFromString have to be given the long name.

> But the problem comes back when plugins themselves have plugins, and
> plugin A needs version 1.0 of plugin C, while plugin B needs version 2.0
[quoted text clipped - 8 lines]
> have had the DLL-Hell problem that required Microsoft to implement this
> fix, so we Mac programmers are out of luck.

Not so, Mac OS X frameworks have a similar versioning mechanism which
accomplishes the same goal. When you link against a framework, you'll
notice that the actual dylib binary you link against has a path like
Blah.framework/Versions/A/Blah. If Blah ever releases a new major version
which is binary incompatible with the old version, then it can start
putting the new version in Versions/B/Blah and leave the A version
present. Old code continues to work, new code gets the new version. If
Blah does their job well, both A and B can be loaded into the same process
without a problem, and everything Just Works.

The main problem with this is not that there's no versioning system, but
that Objective-C absolutely forbid having two classes with the same name
in the same process no matter what they're source. This is inherent in the
way Objective-C works and no amount of loader trickery will solve it.

The good news is that the way Objective-C works also makes it extremely
rare to have a binary-incompatible major revision. It's usually fairly
simple to make changes in such a way that old code can still use yours
without having to be recompiled.

There are still some situations where things will break. Like with the
plugins example, if the plugins bundle the other code inside the plugin,
and you load the plugin with the old version first, the other plugin is
stuck either using the old version or not being able to load at all. And
without special logic it will load its version anyway, causing strange
behavior. To avoid this, it's probably best not to bundle frameworks or
other plugins inside a plugin, but rather to copy them to some common
area.

It seems to me that these questions are mostly academic because the only
problem I've personally seen is one where two plugins have the same class
names directly in themselves, not in their dependencies. Have other people
run into more complicated conflicts in real-world situations?

Signature

Michael Ash
Rogue Amoeba Software

David Phillip Oster - 30 Dec 2006 17:12 GMT
> Not so, Mac OS X frameworks have a similar versioning mechanism which
> accomplishes the same goal. When you link against a framework, you'll
[quoted text clipped - 10 lines]
> in the same process no matter what they're source. This is inherent in the
> way Objective-C works and no amount of loader trickery will solve it.

Thanks for clarifying this. Thank you Michael, always a pleasure to read
your writing.
Michael Ash - 30 Dec 2006 17:44 GMT
>> The main problem with this is not that there's no versioning system, but
>> that Objective-C absolutely forbid having two classes with the same name
[quoted text clipped - 3 lines]
> Thanks for clarifying this. Thank you Michael, always a pleasure to read
> your writing.

Aww, thanks. :) The same goes to you, by the way. For example, I had no
idea about that XML business for Windows DLLs.

Signature

Michael Ash
Rogue Amoeba Software

 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.