Language: C++/C Android Makefile System: https://developer.android.com/ndk/guides/android_mk
I have an application which open a shared library foo.so
and within foo.so we open three other shared libraries bar1.so
, bar2.so
and bar3.so
in three different threads (pthread_create) but in same application/process.
pid is same, thread id is different for bar1, bar2, bar3
Each of bar1.so
, bar2.so
, bar3.so
have Entry
functions which are called using dlsym
after dlopen
and different types of objects are created within bar1 2 3.so
libs
bar1.so
, bar2.so
and bar3.so
also have dynamic linking to another shared library called baz.so
which has some common structs/routines. baz.so
Not explicitly 'dlopen' ed. In make files of bar1.so, bar2.so, bar3.so I specify baz.so
as a shared library which it needs. I want to create a singleton structure in baz.so
where each of bar1.so
, bar2.so
and bar3.so
can write and read to/from.
I tried creating a static object in baz.so
but bar1.so
, bar2.so
and bar3.so
seems to get their distinct copies of the structure. Its not shared.
By Distinct copies i mean that according to code snippet below, when I read in bar2.so , sharedData.a
is 10 and not 22
baz.so:
Filename: sharedobject.h -> All code is defined in sharedobject.h file in baz.so
struct Config {
int a;
bool b;
// Constructor
Config (int val1, bool val2) {
a = val1;
b = val2;
}
};
class SharedObject {
public:
Config sharedData;
SharedObject() {
// Initialize some common data here which will be read
// and written to
sharedData.a = 10;
sharedData.b = 20;
}
static SharedObject* GetInstance() {
static SharedObject singletonObjectInstance;
return &singletonObjectInstance;
}
// Data update function called by either of bar1, bar2 or bar3.so
static void UpdateData(Config &data) {
// Lock : Proper Locking is there but not shown in code
SharedObject::GetInstance()->sharedData.a = data.a;
// Unlock
}
}
Android.mk:
LOCAL_SRC_FILES := // Empty fields
LOCAL_INC_FILES := // Empty Fields
LOCAL_MODULE := baz
include $(BUILD_SHARED_LIBRARY) # This will build baz.so
bar1.so: Let's say Thread1 under ProcessX updates some data
Filename: classx.cpp
#include "sharedobject.h"
void ClassX::WriteToCommonData() {
SharedObject *pSharedObject= SharedObject::GetInstance();
print("Object Address:%p", pSharedObject); // These addresses are not same in bar1 and bar2 which is the problem
Config data(22, false);
SharedObject::UpdateData(data);
}
In Android.mk of bar1.so
Linking is done by specifying shared lib: -> https://developer.android.com/ndk/guides/android_mk#local_shared_libraries
LOCAL_SRC_FILES := classx.cpp
LOCAL_SHARED_LIBRARIES := baz.so
LOCAL_CFLAGS := # No Special flags used.
LOCAL_MODULE := bar1
include $(BUILD_SHARED_LIBRARY) # This will build bar1.so
bar2.so: Lets's say Thread2 under same ProcessX wants to read it now
Filename: classy.cpp
#include "sharedobject.h"
void ClassY::ReadFromCommonData() {
SharedObject *pSharedObject= SharedObject::GetInstance();
print("Object Address:%p", pSharedObject); // These addresses are not same in bar1 and bar2 which is the problem
// Read values updated by bar1.so
print(pSharedObject->sharedData.a); // It is 10, not 22
}
In Android.mk
LOCAL_SHARED_LIBRARIES := baz.so
LOCAL_SRC_FILES := classy.cpp
LOCAL_CFLAGS := # No Special flags used.
LOCAL_MODULE := bar2
include $(BUILD_SHARED_LIBRARY) # This will build bar2.so
Even though all bar libraries are under same Process, do I still need to use Shared memory APIs ?
I have checked these links but it does not seem to answer my question: how to share a single shared library(*.so) instance between two applications Shared Library Structure
class __attribute__ ((visibility ("default")) SharedObject
Defining the class as above solved the issue. It seems like without this, symbol is not exported and not available for dynamic linker.