如何从.dll

时间:2015-08-04 13:55:30

标签: c++ windows linker cmake visual-studio-2015

我有一个动态加载共享库的主可执行文件,两者都在同一个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上正常运行?

1 个答案:

答案 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()