2016-08-15 68 views
1

我的C++应用程序使用dlopen和朋友实现了一个插件系统,其中必要时加载了共享库。应用程序的访问全局变量可执行文件时共享库链接器错误

部分原因是宏观

#define LOG_STREAM (lock_guard<mutex>(CERR_MUTEX), cerr) 

,我用它来保护cerr <<表达式的预处理器。 CERR_MUTEX是一个全球std::mutex变量,该变量在.cpp中定义,头中对应的extern声明。整个可执行文件都使用了LOG_STREAM,没有任何问题。

插件也使用LOG_STREAM来记录它们的日志消息。不幸的是,插件编译失败,出现链接错误

Undefined symbols for architecture x86_64: "_CERR_MUTEX" 

我使用cmake进行插件编译。 CMakeLists中的相关行是

file(GLOB WORKLOAD_SOURCES "workloads/*.cpp") 
foreach(SRC ${WORKLOAD_SOURCES}) 
    get_filename_component(WORKLOAD_NAME ${SRC} NAME_WE) 

    add_library(${WORKLOAD_NAME} MODULE ${SRC}) 
    set_target_properties(${WORKLOAD_NAME} PROPERTIES ${TARGETPROPS}) 
    target_link_libraries(${WORKLOAD_NAME} ${TBB_LIBRARIES} ${Boost_LIBRARIES}) 
endforeach(SRC) 

我也尝试用一个类的静态成员替换普通全局变量。同样的错误。

任何想法这是什么原因,以及如何解决它将不胜感激。

回答

0

最终,链接程序找不到变量,因为该插件不是,而是与可执行文件链接,并且无法看到在此处定义的定义。

偶然,编译工作的插件的其余部分,因为其他符号都链接为weak symbol,这不需要在链接过程中的定义。

我将重构应用程序并将插件所需的类型移动到专用共享库中。该库可以通过可执行文件和插件进行链接。