Вы можете скопировать статическую библиотеку и переименовать все символы, которые используют глобальное состояние. Поскольку символы скомпилированы с c ++, вам не повезло, символы искажены.
Вы можете написать интерфейс C для всех обращений и перекомпилировать статическую библиотеку, скрывая ее символы, а затем использовать некоторые objcopy --prefix-symbols
или g++ -Wl,--wrap=printA
для префикса / переименования символов C.
Или вам нужно заранее знать уже искаженные имена C ++, а затем вызывать objcopy --redefine-sym _Z6printAv=_Z10printAcopyv
и т. Д. Для каждого символа, который экспортирует библиотека.
Ниже приведена тестовая настройка, которая вызывает objcopy
для искаженных имен. Я узнал имена символов, проверив объектные файлы nm a.o
и nm c.o
. Вот оно:
cat <<EOF >Makefile
all: liba.a b.o main.o c.o
# we have access only to liba.a only
objcopy --redefine-sym _Z6printAv=_Z10printAcopyv liba.a libacopy.a
g++ main.o b.o c.o liba.a libacopy.a -o a.out
./a.out
liba.a: a.o
ar rcs liba.a a.o
clean:
rm -fr *.o *.a *.out tmp
EOF
cat <<EOF >a.cpp
#include <iostream>
static int i = 0;
void printA(){
std::cout << i++ << std::endl;
}
EOF
cat <<EOF >b.cpp
void printA();
void printB(){
printA();
}
EOF
cat <<EOF >c.cpp
void printAcopy();
void printC(){
printAcopy();
}
EOF
cat <<EOF >main.cpp
void printB();
void printC();
int main(){
printB();
printB();
printC();
printC();
}
EOF
Вы можете скомпилировать с make
и запустить:
g++ -c -o a.o a.cpp
ar rcs liba.a a.o
g++ -c -o b.o b.cpp
g++ -c -o main.o main.cpp
g++ -c -o c.o c.cpp
# we have access only to liba.a only
objcopy --redefine-sym _Z6printAv=_Z10printAcopyv liba.a libacopy.a
g++ main.o b.o c.o liba.a libacopy.a -o a.out
./a.out
0
1
0
1