Use RTLD_DEFAULT on Android

dlopen()ing NULL (the main program) and dlsym()ing on that handle does
not work on Android as in GNU/Linux. So don't bother with that, just
call dlsym(RTLD_DEFAULT, symbol) instead.

But, it doesn't help, it won't find the type_infos anyway, as they are
weak symbols and the dlsym() at least in Android 4.0 does not like
weak symbols, "Symbol is not global."

So the fallback branch that dynamically generates a type_info, which
normally should get used only for inter-process UNO (and thus
presumably never on Android) is taken instead.

But, that didn't work either at least with NDK r7 thanks to a bug in
its libgnustl_shared.so. But we now patch that at run-time in
android_main() in sal/osl/android/jni/lo-bootstrap.c.

Are we having fun yet?
This commit is contained in:
Tor Lillqvist
2011-11-24 19:02:17 +02:00
parent 5df8678709
commit c366d95851

View File

@@ -108,7 +108,9 @@ namespace CPPU_CURRENT_NAMESPACE
t_rtti_map m_rttis;
t_rtti_map m_generatedRttis;
#ifndef ANDROID
void * m_hApp;
#endif
public:
RTTI() SAL_THROW( () );
@@ -118,13 +120,17 @@ namespace CPPU_CURRENT_NAMESPACE
};
//____________________________________________________________________
RTTI::RTTI() SAL_THROW( () )
#ifndef ANDROID
: m_hApp( dlopen( 0, RTLD_LAZY ) )
#endif
{
}
//____________________________________________________________________
RTTI::~RTTI() SAL_THROW( () )
{
#ifndef ANDROID
dlclose( m_hApp );
#endif
}
//____________________________________________________________________
@@ -153,7 +159,14 @@ namespace CPPU_CURRENT_NAMESPACE
buf.append( 'E' );
OString symName( buf.makeStringAndClear() );
#ifndef ANDROID
rtti = (type_info *)dlsym( m_hApp, symName.getStr() );
#else
rtti = (type_info *)dlsym( RTLD_DEFAULT, symName.getStr() );
// Unfortunately dlsym for weak symbols doesn't work in
// Android 4.0 at least, sigh, so we will always take the
// else branch below.
#endif
if (rtti)
{
@@ -165,11 +178,22 @@ namespace CPPU_CURRENT_NAMESPACE
{
// try to lookup the symbol in the generated rtti map
t_rtti_map::const_iterator iFind2( m_generatedRttis.find( unoName ) );
if (iFind2 == m_generatedRttis.end())
{
// we must generate it !
// symbol and rtti-name is nearly identical,
// the symbol is prefixed with _ZTI
#ifdef ANDROID
// This code is supposed to be used only used for
// inter-process UNO, says sberg. Thus it should
// be unnecessary and never reached for
// Android. But see above...
// OSL_ASSERT (iFind2 != m_generatedRttis.end());
// return NULL;
#endif
char const * rttiName = symName.getStr() +4;
#if OSL_DEBUG_LEVEL > 1
fprintf( stderr,"generated rtti for %s\n", rttiName );