Here is what I’m testing right now : http://gruntthepeon.free.fr/blog/index.php/2010/03/10/39-avoiding-objective-c-class-name-conflicts-with-brute-force . I’m defining JUCE_ObjCExtraSuffix to an easily searchable string , and replace it by a randomly generated string after compilation of the plugin. Maybe I’ll find out later that there is some terrible side-effect of just editing the compiled binary, but so far it seems to work fine, no more conflicts. That way I am not forced to rebuild juce for each project.
Well it looks great, i could link to JUCE and not add amalgamated witch would speed up my build a lot. Is there a list of class names that should be replaced with random string, could you give us a hint on how to do this with juce ?
The list of classes is all those that use the JUCE_ObjCExtraSuffix , so you just have to define JUCE_ObjCExtraSuffix to something like OMGOMGOMGWTF and then do the search&replace on the final binary
Hi Jules and all,
I am encountering similar issues related to (I guess) a conflict between two Juce plugins: I have compiled two AU plugins, one being the demo, the other a home-made. The issue is the following:
. with Digital Performer, only one plugin out of both (mine) prompts without problem. The other (the demo) has not keyboard focus, does not respond to mouse. And if I’m too hectic with the mouse it crashes
. with Logic, there is a similar issue, but even worse: the UI for the Demo plugin is not even shown.
If I delete one or another of the components, the remaining works fine.
I put a unique suffix for each of them, right above the inclusion of juce_amalgamated.mm. It seems to be taken into account, since I have much less library conflict reports with “auval -a”. But I still have three of them:
objc: Class ThreadSafeNSOpenGLView is implemented in both /Users/baskind/Library/Audio/Plug-Ins/Components/IKspatPlugJuce.component/Contents/MacOS/IKspatPlugJuce and /Users/baskind/Library/Audio/Plug-Ins/Components/JuceDemoPlugin.component/Contents/MacOS/JuceDemoPlugin. One of the two will be used. Which one is undefined.
objc: Class JucePlugin_AUExportPrefix_UICreationClass is implemented in both /Users/baskind/Library/Audio/Plug-Ins/Components/IKspatPlugJuce.component/Contents/MacOS/IKspatPlugJuce and /Users/baskind/Library/Audio/Plug-Ins/Components/JuceDemoPlugin.component/Contents/MacOS/JuceDemoPlugin. One of the two will be used. Which one is undefined.
objc: Class JuceUIViewClass is implemented in both /Users/baskind/Library/Audio/Plug-Ins/Components/IKspatPlugJuce.component/Contents/MacOS/IKspatPlugJuce and /Users/baskind/Library/Audio/Plug-Ins/Components/JuceDemoPlugin.component/Contents/MacOS/JuceDemoPlugin. One of the two will be used. Which one is undefined.
I thus looked in to the code of juce_amalgamated.cpp and, imitating the declaration of the other interfaces, I added the following line just above the declaration of the ThreadSafeNSOpenGLView interface:
#define ThreadSafeNSOpenGLView MakeObjCClassName(ThreadSafeNSOpenGLView)
It removes the first error message from “auval -a”, but I still have the two others, and it still crashes… I found the interface JuceUIViewClass in juce_AU_Wrapper.mm, but JucePlugin_AUExportPrefix_UICreationClass nowhere. And I’m not able to add an equivalent definition to JuceUIViewClass since MakeObjCClassName is only defined in juce_amalgamated.cpp.
Any suggestions ?
i have to add, i actually used the binrepl method and it works great, no need to set any prefixes and modify any code, i just added a post-build step in Xcode that does all the work, no need to worry about anything the program does all the work and generates random class names every time. i use it for both AU and VST.
alexis, please try the tip before reporting problems. The ThreadSafeNSOpenGLView thing was fixed a long time ago, and perhaps the other stuff is too. It wastes both your time and mine when people report bugs in old code.
Sorry, you’re right, I downloaded the latest zip from sourceforge but it was not the latest version of the code. I used git and it’s fine.
Would it be possible to have an app level define which omits compiling all the objective c code that requires a different class name to not clash, and then let each wrapper define a unique suffix and pull in all the files it needs? (This kind of thing is already done to define the JuceUIViewClass in the AU wrapper)
sorry, not sure I follow what you mean there?
Is it possible to #include the same objective c code multiple times, once for each plugin type that requires it to define a unique non-conflicting global name. The vst, au, and rtas wrapper code itself could #include all the objective c code from the juce core, but #define a unique extension based on the plugin name or some such thing. This way you would only have to compile the plugin once and it will still work when simply copied to different folders. There might need to also be another conditional part to only compile all code which remains identical once so not to be multiply defined.
wasn’t this issue fixed with this http://www.rawmaterialsoftware.com/juceforum/viewtopic.php?p=24594 patch?
I see what you’re saying andy, but don’t think it’d be possible - there are too many interdependencies between the plugin code, the c++ library code, and the obj-c stuff. Can’t really think how you could stop the linker just mashing it all together and failing.
This works excellent for replacing the suffix. Now, in my endless naivety I thought I could replace any string in a compiled binary with this method. For instance, I have a label a la
Label *somelabel = new Label(T("dummylabel"),T("dummystring")) and want to replace “dummystring” with another string after compilation. However, binrepl finds zero occurrences of “dummystring”. Where is the error in my thought process?
strings are compiled in as bytecode and juce uses UTf8 to store strings, so you propably won’t find it this way.
Hmm… any other possibilities to do this? I’ve tried it with Perl also but without success (probably for the same reason).
If you use the T macro, it’ll be encoded in the binary as wide-chars, which is probably why your tool isn’t finding it.
Hacking a binary sounds like a Very Bad Idea to me - there are bound to be problems with checksums, and compilers perform all sorts of tricks with their constant data - e.g. If your program uses “abcd” and “bcd” in different places, the compiler will probably just create a single block “abcd” in the binary and use different parts of it for the two constants.