我有一个动态加载共享库的主可执行文件,两者都在同一个CMake文件中编译。该库调用主可执行文件中定义的函数,在Linux中这已成功完成并且程序按预期工作,但是在Windows中,库无法链接可执行文件和程序在编译期间崩溃。
我正在使用这个cmake文件构建一个可执行文件和一个库,我从我发现的here的Unix版本中修改过。
CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
PROJECT(EXPORTS C)
SET(CMAKE_VERBOSE_MAKEFILE ON)
SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
FILE(WRITE ${CMAKE_BINARY_DIR}/main.c
"#include <windows.h>
#include <stdio.h>
void internal(void){printf(\"internal()\\n\");}
int main(void)
{
HMODULE plugin_library = LoadLibrary (\"./plugin.dll\");
FARPROC initizer = GetProcAddress(plugin_library, \"external\");
initizer();
}\n")
ADD_EXECUTABLE(main main.c)
target_link_libraries(main ${CMAKE_DL_LIBS})
SET_TARGET_PROPERTIES(main PROPERTIES
ENABLE_EXPORTS TRUE)
FILE(WRITE ${CMAKE_BINARY_DIR}/plugin.c
"void external(void){internal();}\n")
ADD_LIBRARY(plugin MODULE plugin.c)
TARGET_LINK_LIBRARIES(plugin main)
当我尝试构建程序时,我得到了这个输出,它会抛出错误fatal error U1073: don't know how to make 'main.lib'
。
C:\Users\User\Desktop\linkingdemo\build>nmake
Microsoft (R) Program Maintenance Utility Version 14.00.23026.0
Copyright (C) Microsoft Corporation. All rights reserved.
"C:\Program Files\CMake\bin\cmake.exe" -HC:\Users\User\Desktop\linkingdemo -BC:\Users\User\Desktop\linkingdemo\build --check-build-system CMakeFiles\Makefile.cmake 0
"C:\Program Files\CMake\bin\cmake.exe" -E cmake_progress_start C:\Users\User\Desktop\linkingdemo\build\CMakeFiles C:\Users\User\Desktop\linkingdemo\build\CMakeFiles\progress.marks
"C:\Program Files\Microsoft Visual Studio 14.0\VC\BIN\nmake.exe" -f CMakeFiles\Makefile2 /nologo - all
"C:\Program Files\Microsoft Visual Studio 14.0\VC\BIN\nmake.exe" -f CMakeFiles\main.dir\build.make /nologo -L CMakeFiles\main.dir\depend
"C:\Program Files\CMake\bin\cmake.exe" -E cmake_depends "NMake Makefiles" C:\Users\User\Desktop\linkingdemo C:\Users\User\Desktop\linkingdemo C:\Users\User\Desktop\linkingdemo\build C:\Users\User\Desktop\linkingdemo\build C:\Users\User\Desktop\linkingdemo\build\CMakeFiles\main.dir\DependInfo.cmake --color=
Scanning dependencies of target main
"C:\Program Files\Microsoft Visual Studio 14.0\VC\BIN\nmake.exe" -f CMakeFiles\main.dir\build.make /nologo -L CMakeFiles\main.dir\build
"C:\Program Files\CMake\bin\cmake.exe" -E cmake_progress_report C:\Users\User\Desktop\linkingdemo\build\CMakeFiles 1
[ 50%] Building C object CMakeFiles/main.dir/main.c.obj
C:\PROGRA~1\MICROS~1.0\VC\bin\cl.exe @C:\Users\User\AppData\Local\Temp\nm3E0E.tmp
main.c
Linking C executable main.exe
"C:\Program Files\CMake\bin\cmake.exe" -E vs_link_exe C:\PROGRA~1\MICROS~1.0\VC\bin\link.exe /nologo @CMakeFiles\main.dir\objects1.rsp @C:\Users\User\AppData\Local\Temp\nm3FE4.tmp
"C:\Program Files\CMake\bin\cmake.exe" -E cmake_progress_report C:\Users\User\Desktop\linkingdemo\build\CMakeFiles 1
[ 50%] Built target main
"C:\Program Files\Microsoft Visual Studio 14.0\VC\BIN\nmake.exe" -f CMakeFiles\plugin.dir\build.make /nologo -L CMakeFiles\plugin.dir\depend
"C:\Program Files\CMake\bin\cmake.exe" -E cmake_depends "NMake Makefiles" C:\Users\User\Desktop\linkingdemo C:\Users\User\Desktop\linkingdemo C:\Users\User\Desktop\linkingdemo\build C:\Users\User\Desktop\linkingdemo\build C:\Users\User\Desktop\linkingdemo\build\CMakeFiles\plugin.dir\DependInfo.cmake --color=
Scanning dependencies of target plugin
"C:\Program Files\Microsoft Visual Studio 14.0\VC\BIN\nmake.exe" -f CMakeFiles\plugin.dir\build.make /nologo -L CMakeFiles\plugin.dir\build
"C:\Program Files\CMake\bin\cmake.exe" -E cmake_progress_report C:\Users\User\Desktop\linkingdemo\build\CMakeFiles 2
[100%] Building C object CMakeFiles/plugin.dir/plugin.c.obj
C:\PROGRA~1\MICROS~1.0\VC\bin\cl.exe @C:\Users\User\AppData\Local\Temp\nm43BB.tmp
plugin.c
C:\Users\User\Desktop\linkingdemo\build\plugin.c(1): warning C4013: 'internal' undefined; assuming extern returning int
NMAKE : fatal error U1073: don't know how to make 'main.lib'
Stop.
NMAKE : fatal error U1077: '"C:\Program Files\Microsoft Visual Studio 14.0\VC\BIN\nmake.exe"' : return code '0x2'
Stop.NMAKE : fatal error U1077: '"C:\Program Files\Microsoft Visual Studio 14.0\VC\BIN\nmake.exe"' : return code '0x2'
Stop.
如何让这个程序在Windows上正常运行?
答案 0 :(得分:0)
在Windows中,您必须在远程库可以访问的所有功能上指定__declspec(dllexport)
。我已经将它添加到需要由外部库运行的每个函数中,程序现在可以正常工作。
CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
PROJECT(EXPORTS C)
SET(CMAKE_VERBOSE_MAKEFILE ON)
SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
FILE(WRITE ${CMAKE_BINARY_DIR}/main.c
"#include <windows.h>
#include <stdio.h>
__declspec(dllexport) void internal(void){printf(\"internal()\\n\");}
int main(void)
{
HMODULE plugin_library = LoadLibrary (\"./plugin.dll\");
FARPROC initizer = GetProcAddress(plugin_library, \"external\");
initizer();
}\n")
ADD_EXECUTABLE(main main.c)
target_link_libraries(main ${CMAKE_DL_LIBS})
SET_TARGET_PROPERTIES(main PROPERTIES
ENABLE_EXPORTS TRUE)
FILE(WRITE ${CMAKE_BINARY_DIR}/plugin.c
"__declspec(dllexport) void external(void){internal();}\n")
ADD_LIBRARY(plugin MODULE plugin.c)
TARGET_LINK_LIBRARIES(plugin main)
使用Visual Studio 2015
使用以下命令构建并运行此程序cmake -G "NMake Makefiles" ..
nmake
main.exe
并打印
internal()