0

语言:C++/C Android Makefile 系统:https ://developer.android.com/ndk/guides/android_mk

我有一个应用程序,它打开一个共享库foo.so并在 foo.so 我们打开其他三个共享库bar1.sobar2.sobar3.so在三个不同的线程(pthread_create)中但在同一个应用程序/进程中。pid 相同,bar1、bar2、bar3 的线程 id 不同

bar1.so, bar2.so,中的每一个bar3.so都具有Entry使用dlsymafter调用的函数,并且在库dlopen中创建了不同类型的对象bar1 2 3.so

bar1.sobar2.so并且bar3.so还具有到另一个名为的共享库的动态链接,该共享库baz.so具有一些常见的结构/例程。baz.so没有明确地 'dlopen' 编辑。在 bar1.so、bar2.so、bar3.so 的 make 文件中,我指定baz.so了它需要的共享库。我想创建一个单例结构,baz.so每个结构都可以写入和读取。bar1.sobar2.sobar3.so

baz.so我尝试在but中创建一个静态对象bar1.sobar2.so并且bar3.so似乎获得了它们不同的结构副本。它不共享。通过不同的副本,我的意思是根据下面的代码片段,当我在 bar2.so 中阅读时,sharedData.a是 10 而不是 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 

即使所有 bar 库都在同一个进程下,我还需要使用共享内存 API 吗?

我已经检查了这些链接,但它似乎没有回答我的问题: 如何在两个应用程序之间共享单个共享库(* .so)实例 共享库结构

4

2 回答 2

0
class __attribute__ ((visibility ("default")) SharedObject

如上所述定义类解决了这个问题。似乎没有这个,符号不会被导出,也不能用于动态链接器。

于 2021-06-16T22:37:55.970 回答
0

你需要的是同步。你UpdateData有“锁定”和“解锁”,我认为它们是线程同步的占位符。至少,他们应该是。但是您的示例在读取变量时没有锁定。读取器和写入器都需要锁定。除了锁定以确保无竞争访问之外,您还需要使用某种机制来确保读取发生写入之后而不是之前。例如,可以使用条件变量。

于 2021-06-11T17:58:20.373 回答