Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I've been looking at questions like:

It seems to me this could be solved with weak symbols. That is, a native component could provide symbols like rand but adorn them with __attribute__((weak)). If the symbol is found in another library, like the standard runtime, then the weakly linked symbol would not be used. On the other hand, if the symbol was missing, then the native component's version would be used.

I'm having trouble locating information on it for Android (too much unrelated noise while searching).

I opened one of my Crypto++/JNI sample projects and added the following to a CPP file. The AutoSeededRandomPool is just a Crypto++ random number generator object (there's nothing special or tricky below).

// CPP file

#ifdef __cplusplus
extern "C" {
#endif

int __attribute__((weak)) rand(void)
{
    int r;

    AutoSeededRandomPool& prng = GetPRNG();
    prng.GenerateBlock(&r, sizeof(r));

    return r;
}

#ifdef __cplusplus
}
#endif

Trying to compile it results in redefinition of int rand(). I've also tried the following:

// CPP file

#ifdef __cplusplus
extern "C" {
#endif

int rand(void) __attribute__((weak));

int random(void)
{
   ...
}

#ifdef __cplusplus
}
#endif

And moving int rand(void) __attribute__((weak)); to the H file produces the same redefinition of int rand().

And I don't receive any errors or warnings about an unknown attribute.

I also see that __GXX_WEAK__ is defined to 1 in the preprocessor, but SUPPORTS_WEAK is not defined, so its mixed signals (perhaps a bug, similar to Define GXX_WEAK to 0 when using -fno-weak).

I'm not sure if I am doing something wrong, or experiencing something like const and weak attribute with c++ code, or something else.

Does Android support weak symbols? If so, how does one use them.


Here a similar Stack Overflow question that does not have an answer:


Some system details:

  • Base system is Mac OS X 10.8.5, fully patched
  • Eclipse 4.4.1 (Luna), fully patched
  • Android NDK Revision 10d
  • GCC 4.9 cross-compiler
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
385 views
Welcome To Ask or Share your Answers For Others

1 Answer

tl;dr; Android does support weak symbols

Note that this is not android-specific it is equally true for ld-linux.so/ld:

This needs some clarification, because there are 2 cases where weak symbols are used:

  1. static libraries/object files
  2. dynamic libraries/executables

(1) For static libraries and object files can define multiple weak symbols and the correct one (strongest or fist) is picked during compile time linking of final object (.so or executable).

(2) For dynamic libraries weak symbols behave the same way as default ones with one exception. This means there is no such thing as weak symbol override for shared libraries. In other words during relocation/dlsym() the first found (GLOBAL) symbol will be returned: weak or default.

For example (here we assume that none of the objects are -Bsymbolic, this is another exception):

| main.executable <- weak (WEAK) definition of foo()
| -> lib1.so <- strong (DEFAULT) definition of foo()
| -> lib2.so <- uses foo()

the lib2.so will use the main.executalbe's implementation of foo(), despite the fast that lib1.so exports DEFAULT foo().

The exception is that WEAK symbols are allowed to remain unresolved during runtime linking process and result in null reference in most useful cases... when in case of unresolved DEFAULT symbol runtime linker fails.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...