views:

396

answers:

5

In our iPhone XCode 3.2.1 project, we're linking in 2 external static C++ libraries, libBlue.a and libGreen.a. libBlue.a globally overrides the "new" operator for it's own memory management. However, when we build our project, libGreen.a winds up using libBlue's new operator, which results in a crash (presumably because libBlue.a is making assumptions about the kinds of structures being allocated). Both libBlue.a and libGreen.a are provided by 3rd parties, so we can't change any of their source code or build options.

When we remove libBlue.a from the project, libGreen.a doesn't have any issues. However, no amount of shuffling the linking order of the libraries seems to fix the problem, nor does any experimentation with the various linking flags. Is there some way to tell XCode to tell the linker to "have libGreen's use of the new operator use the standard C++ new operator rather than the one redefined by libBlue"?

+1  A: 

I'm not sure if this will work, but you can try overriding new locally in your code. In your implementation, you can copy/paste the implementation of the standard new operator. When you need to create a new object in your code, call your new instead of the global new that libBlue has overridden. Then find the author of libBlue and give him a piece of your mind.

Check out http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=40 for a better summary than I can hope to provide.

Edit: Do you mean that code within libGreen.a will call new from libBlue, or do you mean your code creates a "new ClassDefinedInLibGreen( ... )" and ends up using libBlue's new operator? The solution I posted (if it even works) would only work for the latter case, since you don't have access to the source for either third-party library to control operator overrides.

psublue
Unfortunately, code in libGreen.a is calling new, which winds up calling libBlue.a's new method.
mprudhom
A: 

You could isolate libBlue.a and libGreen.a in a separate process effectively creating a server which allows access to the encapsulated functionality through some form of interprocess communication. This clearly has performance implications but solves the global namespace pollution problem.

William Bell
Sadly, this is a client application which I can't break into multiple processes.
mprudhom
A: 

There can be non-technical solutions:

  1. It may be possible to extract functionality, provided by libBlue to separate application.
  2. You can contact support of libBlue. Other people could also have the problem.
  3. Find alternative.

P.S. It is strange, if developers if libBlue did some "smart" thing, without understanding how to fix problem they introduced.

Konstantin
+2  A: 

Perhaps you could investigate using GNU objcopy, something along the lines of objcopy --redefine-sym oldNew=newNew libBlue.a. The biggest problem I see with this is that Apple's developer tool suite doesn't seem to include objcopy. You can install objcopy from MacPorts (sudo port install binutils), but that objcopy probably can't manipulate ARM object files. There are a couple of ARM binutils in MacPorts, and I'm guessing arm-elf-binutils is your best bet.

Barring that, you could possibly disassemble libBlue.a, rename its new operator with a sed script, then reassemble it. Perhaps you could even manipulate the libBlue.a symbol table directly.

mrkj
I was able to use the "nmedit" utility to do pretty much the same thing by hiding the symbols. I made an "unexport.sym" file containing the symbols listed at http://developer.apple.com/mac/library/technotes/tn2007/tn2185.html#TNTAG7 and then ran:nmedit -R unexport.sym libBlue.o -o libBlue-hideen-operators.oThat seems to have done the trick!
mprudhom
A: 

binary editing of the libraries? If the interweb is to be trusted, it is in Mach-O format. See this reference for details.

libBlue.a must include a list of exported symbols. Try renaming its "new" to "neo" or something. libBlue should still be internally consistent, but libGreen will now only find the system "new" when linking.

Or alternately, libGreen.a must include a list of unresolved symbols, including "new", probably in a __DATA,__la_symbol_ptr section. You could replace the instances of "new" with the name of a wrapper function defined in your app that performs same work. (maybe even calling new directly, but that might end up back in libBlue.)

AShelly