6

가정하자 나는 정적 라이브러리에서 단일 클래스 S는, 이것은 다른 동적 라이브러리 D1 D2 D3와 연결 할 수 있습니다싱글 클래스

내가 클래스 S는 별도의있을 것이다 이해하는 것과 그래서

인스턴스가 각각 D1, D2 및 D3에 있으며 이는 단일 노드가 아니더라도 true입니다 (예 : 글로벌)

클래스 S의 여러 복사본을 방지 할 수있는 방법이 있습니까? 싱글 톤 S를 다른 동적 라이브러리에 넣을 수 없습니다.

    Executable 
       / | \ \ 
       D1 D2 D3 D4 
       | | | 
       S S S 

EDIT : 싱글 톤 S 별도로 ... D1 D2 D3과 연결되는 별도의 정적 라이브러리이다.

내가이 샘플 메이크 (가 .DLL 교체입니다 물건을 확인하는 간단한 테스트 케이스를 만들어 :
싱글 톤은 힙에 할당됩니다 만 포인터가

static s::instance() 
{ 
    static smart_ptr<S> ptr = NULL; 
    if(ptr == NULL) ptr = new S; 
    return ptr; 
} 

Edit2가 정적이다. 그래서) 나는 물건을 체크 아웃했다. 나는 우분투와 Cygwin에서 체크했다. g ++ 컴파일러와 동작은 다르다. Cygwin은 2 개의 다른 객체를 만들었지 만 우분투는 1 개의 객체를 만들었습니다

all: dynamic1 dynamic2 main 

static: static.cpp 
    g++ -c -fPIC static.cpp -o obj/static.o 
    ar rvs lib/static.a obj/static.o 

dynamic1: static dynamic1.cpp 
    g++ -fPIC -shared dynamic1.cpp lib/static.a -o lib/libdynamic1.dll 

dynamic2: static dynamic2.cpp 
    g++ -fPIC -shared dynamic2.cpp lib/static.a -o lib/libdynamic2.dll 

main: dynamic1 dynamic2 main.cpp 
    g++ --std=c++11 main.cpp -ldynamic1 -ldynamic2 -o lib/main -L./lib 
+0

귀하의 의도는 무엇입니까? 공유 리소스에 대한 액세스를 제어하려는 경우 프로세스 간 동기화를 사용할 수 있습니다 (예 : [boost] (http://www.boost.org/doc/libs/1_61_0/doc/html/interprocess/synchronization_mechanisms.html)) –

+0

아니요 이것은 프로세스 간의 공유 메모리가 아닙니다. – tejas

+0

@tejas : 왜 Windows에서 S를 DLL로 만들 수 없습니까? –

답변

2

싱글 톤을 구현하는 두 가지 경우가 있습니다.

포인터로 단일 인스턴스 인 경우 getInstance는이 경우 힙에서 동적으로 메모리를 할당합니다.

2, 정적 멤버로 단일 인스턴스 및 메모리 할당이 발생하지 않습니다.

있는 정적 메모리이고 다음 링크가 설명 : 상기 구현 어느 Where are static variables stored (in C/C++)?

는 : D1, D2, D3 및 D4는 (다른 스레드에서 사용 예) 동일한 애플리케이션 및 이와 같은 과정에 있다면, 그들은 동일한 싱글 톤을 공유합니다. D1, D2, D3 및 D4가 상이한 프로세스에 속하는 경우, 즉 이들은 자신의 메모리 공간을 가지며, 따라서 동일한 싱글 톤을 공유하지 않는다.

+0

답변이 다른 것으로 확인되면 제거했습니다. – tejas

+0

이 방법으로 Windows가 작동한다는 것은 놀랍습니다! –

+0

MSVC에서이 대답이 잘못되었음을 발견했습니다. boost_serialization을 정적 라이브러리로 사용하면 정적 라이브러리를 링크하는 모듈 당 한 번 백엔드 싱글 톤 (예 : 정보 유형)을 인스턴스화합니다. 이 차례로이 백엔드 (등록되지 않은 클래스 예외가 발생했습니다)의 전체 목적을 깨뜨린 –

5

동적 링커가 손상되지 않은 경우 아무런 문제가 없어야합니다. 모든 동적 라이브러리에 정적 라이브러리 S의 객체 파일이 실제로 포함되어 있더라도 동적 로더는 똑같은 심볼에 해당하는지 확인하고 전체 응용 프로그램에서 일관되게 같은 주소를 사용해야합니다. 한마디로

이 시스템 가 파손되지 않은 경우 여기


당신의 편집 당 아무런 문제가없는, 진정한 동적 로더를 가지고, 나는 위의 그것이 좋은에 있어야하는 방식인지 확인 세상과 유닉스 계열 시스템과 같은 방식으로 당신은 우분투에서 작동한다고 말하며, FreeBSD에서도 동일하게 작동한다는 것을 확인할 수 있습니다.

하지만 Windows에서는 불행히도 다릅니다. ld.so과 같은 실제 동적 로더가 없지만 내 보낸 함수의 주소 나 DLL의 데이터 만 필요합니다. 결과적으로, 각 DLL은 코드의 자체 복사본을 포함하고이를 병합하기위한 전역 연결 단계가 없기 때문에이를 사용하기 때문에 자체 DLL의 자체 복사본을 사용하게됩니다.

더 나쁜 것은 내가 간단한 해결 방법을 상상할 수 없다는 것입니다. 정적 연결과 동적 연결은 완전히 다른 동작을합니다. 즉, Windows에서 동적 연결을 사용하는 즉시 적어도 두 개의 다른 DLL에서 액세스 할 수있는 단일 또는 모든 공유 데이터가 DLL을 의미하는 단일 위치에 있어야합니다.

TL/DR : 시스템에 실제 동적 로더 (Unix like)가 있으면 정적 또는 동적 연결에 신경 쓰지 않아도되므로 로더 (ld.so)가 신경 써야합니다. Windows에서 동적 로더가없고 실행 시간이 LoadLibrary 인 API 호출이면 공유 데이터는 하나의 모듈에만 있어야합니다.

+0

질문 업데이트 됨 – tejas

+0

@tejas : 답변을 업데이트했습니다 ... –