链接共享库 CMake 和 C++ 时无法解析的外部符号

问题描述 投票:0回答:1

我正在尝试使用 CMake 将新的 C++ 项目链接到 C 库。该库位于here,当独立克隆和编译该库时,我可以运行测试等。但是,当我将其作为 git 子模块添加到我的 C++ 项目中,并尝试将其链接到我的 main.cpp 时文件中,每个被调用的函数都有很多链接器错误:

Severity    Code    Description Project File    Line    Suppression State
Error   LNK2019 unresolved external symbol "__declspec(dllimport) void __cdecl wimp_instr_queue_high_prio_lock(struct _WimpInstrQueue *)" (__imp_?wimp_instr_queue_high_prio_lock@@YAXPEAU_WimpInstrQueue@@@Z) referenced in function main  magnum-wimp main.obj

正在生成 .dll 并将其放置在二进制目录中,正在生成链接符号的 .lib 并将其放置在 lib 目录中。 C++ 项目由一个依赖项文件夹和一个 src 文件夹构成,其中有两个主要的 CMakeLists.txt 文件:

根目录下的CMakeLists.txt

cmake_minimum_required(VERSION 3.5)
project(magnum-wimp CXX)

set_property(GLOBAL PROPERTY USE_FOLDERS ON)

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin/${CMAKE_BUILD_TYPE})
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib/${CMAKE_BUILD_TYPE})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin/${CMAKE_BUILD_TYPE})

add_subdirectory(dependencies)
add_subdirectory(magnum-wimp)

set_target_properties(wimp PROPERTIES FOLDER Dependencies)
set_target_properties(wimp
    PROPERTIES
    ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib/${CMAKE_BUILD_TYPE}"
    LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/${CMAKE_BUILD_TYPE}"
    RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/${CMAKE_BUILD_TYPE}"
)

magnum-wimp/src目录下的CMakeLists.txt:

cmake_minimum_required(VERSION 3.5)
project(magnum-wimp)

add_executable(${PROJECT_NAME} main.cpp)

# Include the directory containing the wimp library headers
target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/dependencies/wimp/wimp/src)

# Add the directory containing the wimp library
target_link_directories(${PROJECT_NAME} PRIVATE ${CMAKE_BINARY_DIR}/lib/${CMAKE_BUILD_TYPE})

# Link against the wimp shared library
target_link_libraries(${PROJECT_NAME} PRIVATE wimp)

我在 src 文件夹中使用了一个类似的 CMakeLists.txt 文件,就像库在测试文件夹中一样,所以我不确定为什么库似乎无法链接到程序 - 在加载 Visual Studio 解决方案时,它似乎是至少指向 .lib 文件。在库存储库中运行测试时,它会编译并链接到 .lib 文件并使用 .dll 文件,没有任何问题,这正是我所期望的。

c++ c cmake linker
1个回答
0
投票

问题是 C 头文件没有包装在 extern“C”块中。这就是为什么代码在测试或其他 C 项目中正确链接,但在 C++ 中失败,因为它使用了不同的链接系统。

如何修复它的示例如下:

extern "C"
{
    #include <header1.h>
    #include <header2.h>
    ...
}

使此更清洁的一种方法是将标头放置在组合头文件中,以避免每次每次包含时都包含该块。如果代码编译为 C++,预处理器检查也可用于仅包装块:

#ifdef __cplusplus
extern "C" {
#endif

#include <header1.h>
#include <header2.h>
...

#ifdef __cplusplus
}
#endif
© www.soinside.com 2019 - 2024. All rights reserved.