2011-08-22 10 views
0

저는 지금 약간 혼란 스럽습니다. 어제 나는 g ++로 -rdynamic을 사용 했더라도 정의되지 않은 기호를 가지고있었습니다. 하지만 지금은 아무런 오류가 없으며 그것은 더욱 혼란 스럽습니다.공유 객체의 앱 객체 사용

제 경우를 설명하기 위해 공유 객체와 같은 일종의 플러그인을 만들고 싶습니다. 나는 아직 최선의 방법을 결정하지 않았습니다.

가) 내 공유 객체에는 모두 매개 변수로 호출되는 register라는 함수가 있습니다. 이것은 플러그인 관리자가 될 것입니다.

B) 내 공유 객체가 클래스를 정의하고로드 할 때 해당 클래스의 인스턴스를 만들고 인스턴스화합니다. 해당 클래스의 생성자에서는 응용 프로그램에서 정적 싱글 톤을 가져오고 자동 등록을 시도합니다.

내 첫 시도가 지금까지 그렇게 좋지 않았다고 말할 수있는 한.

MAIN.CPP

#include "main.hpp" 
#include <iostream> 
#include <cstdio> 
#include <dlfcn.h> 

int S::shared = 0; 

int main(int argc, char** argv){ 
    std::cout << "In main -> " << S::shared << "\n"; 

    void* triangle = dlopen("./libtwo.so", RTLD_LAZY); 

    if(triangle == NULL){ 
     std::cout << "Error while loading so file\n" << dlerror() << "\n"; 
    } 

    std::cout << "In main -> " << S::shared << "\n" << triangle; 
    return 0; 
} 

main.hpp 그 샘플 S :: 공유에서

class S { 
    public: 
    static int shared; 

    S(){ 
     S::shared = 0; 
    }; 
}; 

two.cpp

#include "main.hpp" 
#include <iostream> 

class MyObject { 
    public: 
    MyObject(){ 
     std::cout << "In two -> " << S::shared << "\n"; 
    } 
}; 

MyObject t(); 

내가 공유 할 정적 객체입니다. 이 간단한 테스트에서는 int 만 사용하지만, futur에서는 클래스의 인스턴스가됩니다.

케이스 A)에 대한 나의 유일한 시도는 세그 폴트 (segfault)였습니다 ... 나는 내가 무엇을 놓쳤는 지 정말로 알지 못합니다.

// 결과 지금까지 (오늘)

[email protected]:~/dev/WebDesign/Scproci$ scons -Q 
g++ -o two.os -c -fPIC two.cpp 
g++ -o libtwo.so -shared two.os 
g++ -o main.o -c -fPIC main.cpp 
g++ -o main -Wl,--export-dynamic main.o -ldl 
[email protected]:~/dev/WebDesign/Scproci$ ./main 
In main -> 0 
In main -> 0 
+0

두 번째 방법에 대한 코드 만 표시하고 표시되는 내용에 따라 예상대로 작동하는 것으로 가정하십시오. – diverscuba23

+0

왜 "In two -> 0"이 표시되지 않습니까? –

+0

정의되지 않은 기호는 S :: shared가 main.cpp에 정의되어 있기 때문에 발생하지만 libtwo.so를 연결할 때 정의 된 main.o를 포함하지 않았습니다. – Flame

답변

1
#include "main.hpp" 
#include <iostream> 

class MyObject {  
    public:  
     MyObject(){   
      std::cout << "In two -> " << S::shared << "\n";  
     } 
}; 

MyObject* t; 

__attribute__((constructor)) 
void init_two() 
{ 
    t = new MyObject(); 
} 

__attribute__((destructor)) 
void uninit_two() 
{ 
    delete t; 
} 

예상되는 결과를 가져와야합니다. 포인터는 공용 객체에서 명시 적으로 다루기가 더 쉽기 때문에 사용됩니다. 정규 초기화는 자동으로 발생하지 않기 때문입니다. 포인터를 사용하지 않으려는 경우 클래스에 대한 명시적인 초기화를 제공하고 공유 라이브러리 초기화 함수에서 호출하십시오.

* EDIT *

내가 한 몇 가지 추가 실험과는 기본 생성자를 사용하는 경우로서 다음 기본이 아닌 생성자를 사용하는 경우, 암시 적으로 사용하고 호출 할 것으로 보인다 표준.

MyObject t(); 

통화 :

그래서 당신은 당신을 변화시킬 수

MyObject t; 

그것은 명시 적 초기화 함수를 정의하지 않은 상태로도 작업 줘야 해.

또는

class MyObject { 
public: 
    MyObject() { /* as before */ }; 
    MyObject(int val) 
    { 
     S::shared = val; 
     std::cout << "In two -> " << S::shared << "\n"; 
    } 
}; 

MyObject t(10); 

그것은 컴파일러) (myObject에 t에 있는가에 혼란 도착한다는 표시; 변수 선언이거나 전역 범위의 함수 선언이며이를 함수 선언으로 처리합니다.

+0

실제로 작동하지 않습니다. –

+0

아직 답변으로 표시하지 않았습니다. 질문에 내 의견을 참조하십시오. 동안 언급했다. 아마도 이것이 최선의 방법 일 것입니다. 공유 객체가로드되는 방법에 대한 정의는 매우 모호하게 보이고 컴파일러에 따라 달라질 수 있습니다. 명시 적으로로드 및 언로드 기능을 정의하는 것이 아마도 어쨌든 가장 안전한 방법 일 것입니다. –

+0

동일한 결과를 발견했습니다. MyObject t()는 작동하지 않지만 암시 적으로 작동합니다. 정말 흥미로운 사례입니다. –

0

즉시 나를 점프 문제는 당신이 링크 단위를 분리해야한다는 것입니다. 정적 클래스 멤버는 해당 클래스의 네임 스페이스에 래핑 된 전역 클래스입니다.

두 개의 링크 단위가 있다고 가정하면 주 프로그램과 공유 개체라고하면 두 컴퓨터 모두 글로벌 foo을 가질 수 있으며 고유 한 값이됩니다.

또한 왜 두 개의 cpp에서 t의 정적 초기화가 공유 객체에서 실행되지 않았는지 명확하지 않습니다. 공유 객체의 일부 주요 기능보다 먼저 발생하는 것은 아닙니다.

+0

내 예제에서는 S :: shared가 main.cpp에서만 인스턴스화되기 때문에 두 개의 foo가 존재하지 않을 것입니다. 그것은 정적 링크 된 개체를 잘 작동하지만 난 왜 생성자가 호출되지 않습니다 모르겠다 –