2016-08-15 74 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,這不需要在鏈接過程中的定義。

我將重構應用程序並將插件所需的類型移動到專用共享庫中。該庫可以通過可執行文件和插件進行鏈接。