c - 如何使用 MSVC 在 Windows 上针对 "cdylib"Rust lib 编译+链接一个简单的 hello_world.c

标签 c windows visual-c++ cmake rust

这个问题在这里已经有了答案:





CMake link to external library

(5 个回答)


1年前关闭。




我使用 Rust (crate type = "cdylib") 创建了一个动态库。 Rust/Cargo 产生了两个文件:text_loading_lib.dlltext_loading_lib.dll.lib .我想在 Windows 上构建一个非常简单的项目(hello_world.c),它使用这个库中的一个函数,只使用 MSVC(Microsoft Visual C++ 工具集)和 JetBrains CLion/CMake。
main.c

#include <stdio.h>

typedef unsigned long long usize_t; // 64 bit / usize on 64 bit machine
extern void show_loading_animation_ffi(usize_t, usize_t, int, usize_t (*prog_fn)());

// function that tells the lib how many percent progress we made so far
usize_t progress_reporter() { return (usize_t) 20 }

int main(void) {
    show_loading_animation_ffi(0, 100, TARGET_STDERR, progress_reporter);
    return 0;
}
我熟悉 UNIX 上的这个过程,但我不知道它是如何在 Windows 上完成的。在 UNIX 上,我会在编译期间将共享对象链接到 main.c,并使用 LD_LIBRARY_PATH 提供其位置。在运行时。在 Windows 上是相似的吗?
我还使用 JetBrains CLion 尝试了一个 CMAKE 项目,但仍然没有成功。当我尝试运行 main()main.c从 CLion 开始,总是会出现无法创建目标的错误。使用 Rust 创建的库文件( text_loading_lib.dlltext_loading_lib.dll.lib )与 CMakeLists.txt 位于同一目录中和 main.c .
CMakeLists.txt
cmake_minimum_required(VERSION 3.16)
project(main C)

set(CMAKE_C_STANDARD 11)

add_executable(main main.c)

# the path is correct
target_link_libraries(main text_loading_animation)
#also tried: target_link_libraries(main text_loading_animation.dll)
#also tried:  target_link_libraries(main text_loading_animation.dll.lib)
CLion-输出是:
[ 50%] Linking C executable main.exe
LINK Pass 1: command "C:\PROGRA~2\MICROS~2\2019\COMMUN~1\VC\Tools\MSVC\1426~1.288\bin\Hostx64\x64\link.exe /nologo @CMakeFiles\main.dir\objects1.rsp /out:main.exe /implib:main.lib /pdb:C:\dev\lib-text-loading-animation-rust\calling-from-c-examples\windows\cmake-build-debug\main.pdb /version:0.0 /machine:x64 /debug /INCREMENTAL /subsystem:console text_loading_animation.lib kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib /MANIFEST /MANIFESTFILE:CMakeFiles\main.dir/intermediate.manifest CMakeFiles\main.dir/manifest.res" failed (exit code 1104) with the following output:
LINK : fatal error LNK1104: File "text_loading_animation.lib" can't be opened.
NMAKE : fatal error U1077: ""C:\Program Files\JetBrains\CLion 2020.1.1\bin\cmake\win\bin\cmake.exe"": Return-Code "0xffffffff"
Stop.
NMAKE : fatal error U1077: ""C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.26.28801\bin\HostX64\x64\nmake.exe"": Rückgabe-Code "0x2"
Stop.
NMAKE : fatal error U1077: ""C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.26.28801\bin\HostX64\x64\nmake.exe"": Rückgabe-Code "0x2"
Stop.
NMAKE : fatal error U1077: ""C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.26.28801\bin\HostX64\x64\nmake.exe"": Rückgabe-Code "0x2"
Stop.

最佳答案

我让它与 CMake 以及命令行一起工作。
Cmake: CMakeLists.txt

cmake_minimum_required(VERSION 3.16)
project(main C)

set(CMAKE_C_STANDARD 11)

add_executable(main main.c)
# "*.dll.lib" - important! not just *.dll
target_link_libraries(main ${CMAKE_CURRENT_SOURCE_DIR}/../../target/release/text_loading_animation.dll.lib)

# copy DLL file into target dir
add_custom_command(TARGET main POST_BUILD              # Adds a post-build event to "main"
    COMMAND ${CMAKE_COMMAND} -E copy_if_different      # which executes "cmake - E copy_if_different..."
    "${PROJECT_SOURCE_DIR}/text_loading_animation.dll" # <--this is in-file
    $<TARGET_FILE_DIR:main>)                           # <--this is out-file path
例如,现在您可以在 Jetbrains CLion 中“运行 main”。

命令行(Windows 批处理脚本)
重要的部分是:
  • cl main.c /link text_loading_animation.dll.lib
  • main.exe

  • 完整的批处理脚本:
    @echo off
    
    rem: clean old data
    del main.exe main.obj *.dll *.dll.lib
    
    rem: copy rust lib into current dir
    xcopy /y ..\..\target\release\text_loading_animation.dll .
    xcopy /y ..\..\target\release\text_loading_animation.dll.lib .
    
    
    rem: sets up Visual Studio Compilertoolsuite environment
    call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat"
    
    rem: *.dll.lib contains header information during compile; *.dll is the runtime file that must be in the same directory/path
    
    rem: "cl" is windows compiler: produces main.obj and main.exe; main.obj is not needed in the end;
    rem:   it is only for the stage between compiling and linking
    rem: /W4 is highest warnings flag
    cl /W4 main.c /link text_loading_animation.dll.lib
    del main.obj
    
    rem: now execute
    main.exe
    

    关于c - 如何使用 MSVC 在 Windows 上针对 "cdylib"Rust lib 编译+链接一个简单的 hello_world.c,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62517760/

    相关文章:

    c - if 语句中的字符串比较不起作用

    无法绑定(bind)地址 [47] : Address family not supported by protocol family

    c++ - (ptr - A[0])/(sizeof(A[0])/sizeof(A[0][0])) 的类型是什么?

    python - 使用 Windows API 或 WMI 确定进程是否显示在任务栏中

    c++ - 自定义 WM 配置文件 - 编解码器问题

    windows - 将图像作为按钮控件的背景

    c++ - IncrediBuild - 错误 : First character of string should be '0' or '1'

    c++ - 在 for 循环中声明几个新的计数器

    c++ - 我希望在对右值的引用上调用基于右值的函数......如果有这样的事情

    c++ - 在此 "number of elements"宏中添加虚拟字符的目的是什么?