gpt4 book ai didi

c - Rust cdylib crate,将 dll 链接到 Windows 中的 C 程序

转载 作者:行者123 更新时间:2023-12-03 11:29:10 29 4
gpt4 key购买 nike

我一直在尝试编译一个简单的 rust cdylib在 windows 中创建 crate 并将其与一个简单的 c 程序链接。尽管我做了很多努力,我还是没有链接 dll文件。
最小示例
首先我的rustc版本是:

C:\Users\User> rustc --version
rustc 1.50.0 (cb75ad5db 2021-02-10)
我有一个基本的 Cargo.toml其中包括 cbindgen并设置 crate 类型:
[package]
name = "mycrate"
version = "0.1.0"
authors = ["PauMAVA <--REDACTED-->"]
edition = "2018"

[lib]
name = "mycrate"
crate-type = ["cdylib"]

[build-dependencies]
cbindgen = "0.18.0"
然后是 lib.rs只声明了一个非常简单的 extern hello world 函数:
#[no_mangle]
pub extern "C" fn test_fn() {
println!("Hello world from Rust!")
}
最后,我通过 cdbindgen 生成头文件在 build.rs :
extern crate cbindgen;

use std::env;
use std::path::Path;
use cbindgen::{Config, Builder};

fn main() {
let crate_env = env::var("CARGO_MANIFEST_DIR").unwrap();
let crate_path = Path::new(&crate_env);
let config = Config::from_root_or_default(crate_path);
Builder::new().with_crate(crate_path.to_str().unwrap())
.with_config(config)
.generate()
.expect("Cannot generate header file!")
.write_to_file("testprogram/headers/mycrate.h");
}
生成的标题如下:
/* Generated with cbindgen:0.18.0 */

#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>

void test_fn(void);
我拥有的 C 代码是以下简单程序:
#include <stdio.h>
#include "headers/mycrate.h"

int main() {
printf("Hello world from C!\n");
test_fn();
}
为了澄清,我的文件结构如下:
testprogram
|-- headers
| |-- mycrate.h
|
|-- main.c
|-- mycrate.dll
当我尝试编译和链接时,出现链接器错误:
C:\Users\User\...\testprogram> gcc .\main.c -L.\mycrate.dll -o .\main
c:/mingw/bin/../lib/gcc/mingw32/8.2.0/../../../../mingw32/bin/ld.exe: C:\Users\Pau\AppData\Local\Temp\cccQGbDk.o:main.c:(.text+0x1b): undefined reference to `test_fn'
collect2.exe: error: ld returned 1 exit status
附加信息
奇怪的是,在 WSL (Linux) 中编译时,我得到了 .so正确链接的 Linux 库:
$ gcc main.c -L./mycrate.so -o main
$ ./main
Hello world from C!
Hello world from Rust!
我在这里缺少什么?我想这只是一个链接问题,但我找不到它的来源。任何帮助表示赞赏!
编辑
我也尝试在链接时使用绝对路径。
我目前正在使用 MinGW .
编辑 2
还尝试链接包含库 mycrate.dll.lib由 cargo 产生:
C:\Users\User\...\testprogram> gcc .\main.c -L.\mycrate.dll.lib -o .\main
c:/mingw/bin/../lib/gcc/mingw32/8.2.0/../../../../mingw32/bin/ld.exe: C:\Users\Pau\AppData\Local\Temp\ccL0sH7B.o:main.c:(.text+0x1b): undefined reference to `test_fn'
collect2.exe: error: ld returned 1 exit status
rustc --version --verbose输出是:
C:\Users\User\...\testprogram> rustc --version --verbose
rustc 1.50.0 (cb75ad5db 2021-02-10)
binary: rustc
commit-hash: cb75ad5db02783e8b0222fee363c5f63f7e2cf5b
commit-date: 2021-02-10
host: x86_64-pc-windows-msvc
release: 1.50.0

最佳答案

我认为这里有很多问题。

  • 您为 64 位系统编译库(因为 Rust 是 x86_64 ),但您尝试将其与 32 位 MinGW 链接
  • Rust 正在使用 MSVC工具链,然后您尝试使用 MinGW 编译 C 程序
  • 我对此并不完全确定,但我认为您链接了 mycrate.dll.lib不正确。根据 that answer你应该用 l 作为前缀像这样:-L -lmycrate.dll.lib

  • 显然有多种方法可以解决这个问题。例如,您可以安装 Rust,以便它使用 MinGW工具链如解释 here .
    或者您可以使用 Visual Studio 来编译您的 C 代码。这就是我所做的,因为我不想费心重新安装 Rust(如果错了请纠正我,但我认为没有简单的方法来配置 MSVCMinGW 后端,以便人们可以轻松切换在 Rust 中)。
    VisualStudio 2019编译链接步骤如下:
  • 构建 Rust 项目 cargo build --release使用 MSVC 安装 64 位 Rust
  • 新建 Empty C++项目
  • 添加 main.c并插入您的代码
  • 在放置解决方案文件的同一目录中放置 headers/mycrate.h
  • 复制 mycrate.dllmycrate.dll.lib放入您的解决方案文件所在的同一目录
  • 在 VisualStudio 中右键单击 C++ 项目并选择 属性
  • 选择 Configuration=ReleasePlatform=x64
  • 添加 $(SolutionDir)\headers;C/C++ -> General -> Additional Include Directories
  • 添加 $(SolutionDir)mycrate.dll.lib;Linker -> Input -> Additional Dependencies
  • 申请 所有更改并关闭属性 Pane
  • Release 中构建项目模式与 x64平台

  • 如果您在 Debug模式下构建 Rust 项目(例如 cargo build ),您将必须对 Debug 执行相同的操作模式。
    我知道这是一个复杂的过程,所以让我知道我是否应该制作 Repo 作为该过程的演示......
    正如我所说,如果你喜欢使用 MinGW 构建,您必须按照 here 的说明以不同的方式设置 Rust .

    关于c - Rust cdylib crate,将 dll 链接到 Windows 中的 C 程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66563760/

    29 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com