2014-02-08 2 views
4

에 해결되지 않은 기호 공유 라이브러리를 연결 나는 다음과 같은 세 가지 프로젝트가 있습니다리눅스

  • Host :에 의해로드 된 런타임 라이브러리 : 전역 변수 (선언 통근)
  • Plugin 수출 실행 가능 Host을 참조하고 전역 변수를 참조하십시오.
  • Tool : 실행 파일은 Plugin과 연결되며 일부 기능을 사용합니다. 어떤 식 으로든 전역 변수를 참조하지 않습니다.

이제 Windows에서이 모든 것을 올바르게 작성하면됩니다. ToolPlugin의 내보내기 라이브러리에만 연결되며 전역 변수를 확인하지는 않습니다.

Linux에서 문제가 발생했습니다. ToolPlugin .so 라이브러리 (내보내기 라이브러리가 없기 때문에)와 연결을 시도하고 해결할 수없는 Host의 전역 변수에 대한 참조를 찾습니다.

이 문제를 해결하는 방법은 무엇입니까?


편집 :

다음은 CMake를 사용하여 문제의 컴파일 가능한 예이다.

CMakeLists.txt

SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_CURRENT_SOURCE_DIR}/bin") 
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG "${CMAKE_CURRENT_SOURCE_DIR}/bin") 

SET(CMAKE_POSITION_INDEPENDENT_CODE ON) 

ADD_SUBDIRECTORY(Host) 
ADD_SUBDIRECTORY(Plugin) 
ADD_SUBDIRECTORY(Tool) 

호스트/Host.h

#ifndef HOST_H 
#define HOST_H 

#ifdef _MSC_VER 

#ifdef COMPILE_HOST 
#define HOST_EXPORT __declspec(dllexport) 
#else 
#define HOST_EXPORT __declspec(dllimport) 
#endif 

#else 
#define HOST_EXPORT 
#endif 


class HOST_EXPORT Host 
{ 
public: 
    int getAnswer(); 

}; 


extern HOST_EXPORT Host g_host; 


#endif 

호스트/Host.cpp

#include "Host.h" 
#include "../Plugin/Plugin.h" 
#include <iostream> 


Host g_host; 


int Host::getAnswer() 
{ 
    return 42; 
} 


int main() 
{ 
    std::cout << g_host.getAnswer() << std::endl; 

    // load plugin and use it 
} 

호스트/CMakeLists.txt

PROJECT(Host) 

ADD_EXECUTABLE(Host Host.cpp Host.h) 

ADD_DEFINITIONS(-DCOMPILE_HOST) 

SET_TARGET_PROPERTIES(Host PROPERTIES ENABLE_EXPORTS ON) 
,174,515 15,

플러그인/Plugin.h

#ifndef PLUGIN_H 
#define PLUGIN_H 


class Plugin 
{ 
public: 
    Plugin(); 

}; 

#endif 

플러그인/Plugin.cpp

#include "Plugin.h" 
#include "../Host/Host.h" 
#include <iostream> 


Plugin::Plugin() 
{ 
    std::cout << g_host.getAnswer() << std::endl; 
} 

플러그인/PluginFunc.h

#ifndef PLUGINFUNC_H 
#define PLUGINFUNC_H 

#ifdef _MSC_VER 
#define PLUGIN_EXPORT __declspec(dllexport) 
#else 
#define PLUGIN_EXPORT 
#endif 


namespace plug 
{ 
    int PLUGIN_EXPORT getRandomNumber(); 
} 

#endif 

플러그인/PluginFunc.cpp

#include "PluginFunc.h" 


int plug::getRandomNumber() 
{ 
    return 4; 
} 

플러그인/CMakeLists.txt

PROJECT(Plugin) 

ADD_LIBRARY(Plugin SHARED Plugin.cpp Plugin.h PluginFunc.cpp PluginFunc.h) 

TARGET_LINK_LIBRARIES(Plugin Host) 

도구/Tool.cpp

#include "../Plugin/PluginFunc.h" 
#include <iostream> 


int main() 
{ 
    std::cout << plug::getRandomNumber() << std::endl; 
} 

도구/CMakeLists.Windows에서

PROJECT(Tool) 

ADD_EXECUTABLE(Tool Tool.cpp) 

TARGET_LINK_LIBRARIES(Tool Plugin) 

TXT

는 빌드 및 실행됩니다. Host.exe는 "42"를 표시하고 Tool.exe는 "4"를 표시합니다.

리눅스에

나는 다음과 같은 연결 오류가 발생합니다 :

[email protected]:~/vbox/testlink/build$ make 
Scanning dependencies of target Host 
[ 25%] Building CXX object Host/CMakeFiles/Host.dir/Host.o 
Linking CXX executable Host 
[ 25%] Built target Host 
Scanning dependencies of target Plugin 
[ 50%] Building CXX object Plugin/CMakeFiles/Plugin.dir/Plugin.o 
[ 75%] Building CXX object Plugin/CMakeFiles/Plugin.dir/PluginFunc.o 
Linking CXX shared library libPlugin.so 
[ 75%] Built target Plugin 
Scanning dependencies of target Tool 
[100%] Building CXX object Tool/CMakeFiles/Tool.dir/Tool.o 
Linking CXX executable Tool 
../Plugin/libPlugin.so: undefined reference to `Host::getAnswer()' 
../Plugin/libPlugin.so: undefined reference to `g_host' 
collect2: error: ld returned 1 exit status 
make[2]: *** [Tool/Tool] Error 1 
make[1]: *** [Tool/CMakeFiles/Tool.dir/all] Error 2 
make: *** [all] Error 2 
+0

Win/Linux에서 어떻게 빌드를 볼 수 있도록 코드/빌드 스크립트를 게시 할 수 있습니까? – txtechhelp

+0

@txtechhelp 전체 예제로 내 질문을 업데이트했습니다. – typ1232

+0

실행 파일에 대해 정적으로 링크하는 것은 매우 비 재능입니다. 왜 이렇게해야하는지 어떤 이유로 든 우리는 단지 호기심이 있습니까? – ComicSansMS

답변

1

다른 두 가지 방법은 다음과 같습니다

  • 이 도구의 전역 변수를 정의합니다. 값이 사용되지 않으므로 값은 중요하지 않습니다.
  • 링커 명령을 사용하여 구성된 값이있는 기호를 정의합니다. GCC와 GNU ld와 같아야합니다. gcc -Wl,--defsym=GlobalSymbol=0
1

두 가지 방법이 있습니다 HostPlugin 모두에 의해 참조되는 별도의 DLL에

  1. 이동합니다 전역가.
  2. Tool에 제공하고 플러그인 기능을 Host (라이브러리 호출을 통해 플러그인 구현)으로 제공하면됩니다.

이 두 가지가 도움이 될 것입니다.

Tool 프로그램을 Plugin DLL에 연결하기 때문에 링크가 실패합니다. 이때 링커에서 모든 기호를 해석 할 수 있습니다. 게으른 조회는 기본적으로 런타임시 문제를 피할 수 있지만 시스템 정책은 보안상의 이유로 지연 조회를 금지 할 수 있습니다. 이는 프로세스에서 정의되지 않은 기호가 있기 때문에 호출 직후에 Tool을 종료합니다.

+0

고맙습니다. 이것은 내가 목표로 삼아야 할 장기적인 해결책이지만 이미 알고있었습니다. 너무 많은 노력없이 내 문제를 해결할 수있는 답을 찾고있었습니다. – typ1232