采坑三天,终于解决编译动态库以及动态库给其他工程引用问题,也很感谢同事的帮助,希望遇到该问题可以起到帮助
dll 动态库编译
// MyDll_Name.h
// dll头文件定义宏,编译时应该是dllexport,其他应用引用dll时,编译时应该是dllimport
#ifdef COMPILER_EXPORTS
#define COMPILER_EXPORTS_API __declspec(dllexport)
#else
#define COMPILER_EXPORTS_API __declspec(dllimport)
COMPILER_EXPORTS_API void Dll_Interface();
set(LIB_SRCS
a.cpp
b.cpp
...
)
# 可能会出现动态库需要链接other场景
add_library(other STATIC ${LIB_SRCS})
# SHARED type用于生产dll
add_library(Mydll_Name SHARED Mydll_Name.cpp)
# 编译时定义宏,主要是Mydll_Name.h中定义的宏,用于再编译时接口是exports
target_compile_definitions(Mydll_Name PRIVATE COMPILER_EXPORTS)
target_link_libraries(Mydll_Name other)
测试dll动态库对应CmakeLists.txt
project(main)
cmake_minimum_required(VERSION 3.19)
# SHARED IMPORTED表示外部引用库,不需要进行编译
add_library(MyDll_Name SHARED IMPORTED)
#设置库的路径属性
set_target_properties(MyDll_Name PROPERTIES
#IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/MyDll_Name .dll
IMPORTED_IMPLIB ${CMAKE_CURRENT_SOURCE_DIR}/MyDll_Name .lib
)
add_executable(main main.cpp)
target_link_libraries(main PUBLIC MyDll_Name)
mkdir build
cd build
cmake .. && cmake --build .
编译过程如果遇到error LNK2019: unresolved external symbol "__declspec(dllimport) void __cdecl 报错
1.检查cmake编译正确
2.main测试应用是否和dll编译对应arch是否一致(x86、x64问题)
如果报library machine type ‘x64’ conflicts with target machine type 'x86’问题
cmake --help获取编译信息,编译为64为应用来链接x64对应的dll
cmake -G 'Visual Studio 15 2017 Win64' .. && cmake --build .
如果成功编译后,发现调用dll接口传入string类型参数或STL中类型参数、或接口返回std::string& str、std::vector<>& list
后,在dll中进行对参数进行修改、返回等操作,执行main应用后,修改或返回值都为空,请
检查dll和main编译应用是否都为release、debug、relwithdebinfo,需要双方一致;
假设都为relwithdebinfo
cmake -G 'Visual Studio 15 2017 Win64' .. && cmake --build . --config RelWithDebInfo
执行时需要将dll放在与生成的main.exe同层级目录(Debug、RelWithDebInfo)下
extern "C"{
COMPILER_EXPORTS_API void Dll_Interface();
}