能否让两个共享对象(a.so、b.so)共用同一全局变量并同步值?
Absolutely, this is totally achievable—you just need to avoid a common pitfall where each shared library ends up with its own copy of x. Let’s break down how to make this work, step by step.
Why the default approach fails
If you compile c.cc into an object file (c.o) and link that object directly into both a.so and b.so, each shared library will get its own private copy of int x = 0. When a.so increments its x, it’s modifying memory that’s exclusive to a.so—b.so will never see that change, since it’s reading from its own separate x instance.
The correct way to share x
The key is to ensure both a.so and b.so reference the same instance of x. There are two reliable ways to do this:
1. Compile c.cc into its own shared library
This is the cleanest and most maintainable approach. By putting x in a dedicated shared library (libc.so), both a.so and b.so will link against it and use the single x instance stored in libc.so.
Here’s how to do it with GCC/G++:
- Compile
c.ccinto a shared library:g++ -fPIC -shared c.cc -o libc.so - Compile
a.soto link againstlibc.so:g++ -fPIC -shared a.cc -o liba.so -L. -lc - Compile
b.sothe same way:g++ -fPIC -shared b.cc -o libb.so -L. -lc
In your code:
- In
a.cc, declareextern int x;then modify it (e.g.,void inc_x() { x++; }) - In
b.cc, declareextern int x;then read it (e.g.,int get_x() { return x; })
Now, when a.so calls inc_x(), it’s modifying the x in libc.so—and b.so’s get_x() will return the updated value.
2. Force symbol sharing without a separate shared library
If you don’t want a dedicated libc.so, you can mark x as a globally visible symbol and ensure both shared libraries resolve to the same instance. This is trickier but possible:
- In
c.cc, explicitly markxas visible (to avoid compiler defaults that hide symbols in shared libraries):__attribute__((visibility("default"))) int x = 0; - Compile
c.ccinto a PIC object:g++ -fPIC -c c.cc -o c.o - Link
a.sowithc.o, and ensure symbols are not made private:g++ -fPIC -shared a.cc c.o -o liba.so -Wl,-no-undefined - When linking
b.so, instead of includingc.o, link againstliba.soto reuse itsxinstance:g++ -fPIC -shared b.cc -o libb.so -L. -la
This works because b.so will resolve x to the instance in liba.so instead of creating its own. However, this couples b.so to a.so, which is less flexible than the first approach.
Critical notes
- Never declare
xasstatic—that makes it a private symbol, so no other library can access it. - If your compiler uses
-fvisibility=hiddenby default (common in some distros or build setups), you must explicitly markxas visible with__attribute__((visibility("default")))or compile with-fvisibility=default. - When testing, make sure your loader can find the shared libraries (use
LD_LIBRARY_PATH=.on Linux to include the current directory).
内容的提问来源于stack exchange,提问作者imp

