2013-08-21 2 views
2

질문은 this one과 매우 유사하지만 거기에 언급 된 해결책은 유용하지 않았습니다.리눅스 공유 라이브러리의 전역 변수의 단일 사본

로컬 전역 변수를 사용하는 함수로 공유 라이브러리 B가 있다고 가정합니다. 이 함수는 두 번째 공유 라이브러리에서 호출됩니다.

B와 C 모두 A에서 사용되며 각자 고유 한 전역 변수 인스턴스를 가질 것으로 예상되지만 어떻게 든 컴파일러는이를 가리 키도록 링크를 관리합니다. 동일한 개체 (Windows와 달리).

누군가 내가 A에서 전역 변수의 다른 인스턴스를 가질 수있는 방법을 제안 할 수 있습니까?

아래 코드는 제 코드입니다. a.out을 실행하면 , 나는 그러나

1 
calling from someCFunc(): 1 

을 얻을 기대, 내가 얻을 :

1 
calling from someCFunc(): 2 

BH :

#ifndef _B_H_ 
#define _B_H_ 

extern "C" __attribute__ ((visibility("default"))) void myFunc(); 

#endif 

b.cpp :

#include "b.h" 
#include <iostream> 

int myGlobal = 0; 

extern "C" __attribute__ ((visibility("default"))) void myFunc() 
{ 
    ++myGlobal; 
    std::cout << myGlobal << "\r\n"; 
} 

채널 :

#ifndef _C_H_ 
#define _C_H_ 

extern "C" __attribute__ ((visibility("default"))) void someCFunc(); 

#endif 

c.cpp

#include "c.h" 
#include "b.h" 
#include <iostream> 

extern "C" __attribute__ ((visibility("default"))) void someCFunc() 
{ 
    std::cout << "calling from someCFunc(): "; 
    myFunc(); 
} 

a.cpp :

#include "b.h" 
#include "c.h" 

int main(void) 
{ 
    myFunc(); 
    someCFunc(); 

    return 0; 
} 

buildscript :

rm *.so 
rm *.out 
g++ -fPIC -fvisibility=hidden -shared b.cpp -o libb.so 
g++ -fPIC -fvisibility=hidden -shared b.cpp -o libb2.so 
g++ -fPIC -fvisibility=hidden -shared c.cpp -o libc.so -l:libb.so 
g++ a.cpp -fPIC -fvisibility=hidden -l:libb2.so -l:libc.so 
+0

c.cpp의 근원은 무엇입니까? – bennofs

+0

@bennofs - 소스가 추가되었습니다. –

답변

1

B와 C 둘 다 사용하는, 나는 것 각자가 글로벌 변수의 인스턴스를 가질 것을 기대한다. e

예상 사항이 잘못되었습니다. 여기서 관찰하고있는 것은 정확하고 예상되는 행동입니다. 만약 당신이 기대하는 것이 사실이라면, 거기에있는 모든 도서관은 악명 높은 다이아몬드 클래스 계층 구조와 비슷한 문제에 직면하게 될 것입니다.

누군가 내가 A에서 전역 변수의 다른 인스턴스를 가질 수있는 방법을 제안 할 수 있습니까?

내가 아는 한, 이것은 C++에서는 불가능합니다. 다른 변수를 사용하려면 별도로 정의하고 함수에 대한 참조를 전달해야합니다.

// B 
void myFunc(int& myVar) { 
    ++myVar; 
    std::cout << myVar << "\r\n"; 
} 

// C 
int myGlobalC = 0; 
void someCFunc() { 
    myFunc(myGlobalC); 
} 

// A 
int myGlobalA = 0; 
int main() { 
    myFunc(myGlobalA); 
    someCFunc(); 
} 
+0

VS2010 (__attribute __ ...을 __declspec (dllexport)으로 변경)에서 코드를 실행할 때 예상되는 결과를 얻었으므로 가능합니다. 같은 것을 모방하는 방법이 있어야합니다 리눅스에서의 행동 –

+0

간단하게 설명하자면 : A의 관점에서, 그것은 b2와 c라는 두 개의 다른 라이브러리를 사용합니다. 그들의 행동이 어떤 식 으로든 연결될 것으로 기대하지는 않습니다. b2가 다른 소스 코드 (foo.cpp, foo.h) 전역 정수가 myGlobal인데 왜 c라는 다른 라이브러리에서 사용되는 변수에 연결해야합니까 ?? –

+0

@MarkS 나쁘다. 나는 다르게 명명 된 두 개의 동일한 라이브러리가 있다는 사실을 간과했다. 긴 이야기 짧게 : 런타임 링커 (라이브러리 로더)가 Windows와 같은 방식으로 심볼을 처리하지 않기 때문에 리눅스에서이 작업을 수행 할 수 없습니다. 충돌 한 기호는 최신로드 된 라이브러리에 의해 "대체"됩니다. 나는 구체적인 대답을 위해 지금 당장 시간이 없지만 최대한 빨리 한 가지씩 정리해 보겠습니다. 어쩌면'dlopen'도 도움이 될지 모르지만 이것은 일종의 해킹입니다. – syam

관련 문제