-1

我想使用 Rust 文件main.rs来绑定src/c_ffi/myharfbuzz.c链接动态库的 C 文件(例如hb.hand hb-ot.h)。当我用 编译它时cargo run,它显示错误:

/usr/bin/ld: .../target/debug/build/uahji2-109ed7d174e31932/out/libmyharfbuzz.a(myharfbuzz.o): in function `example':
.../src/c_ffi/myharfbuzz.c:18: undefined reference to `hb_blob_create_from_file'
      /usr/bin/ld: .../src/c_ffi/myharfbuzz.c:19: undefined reference to `hb_face_create'
      /usr/bin/ld: .../src/c_ffi/myharfbuzz.c:21: undefined reference to `hb_ot_var_get_axis_count'
      /usr/bin/ld: .../src/c_ffi/myharfbuzz.c:22: undefined reference to `hb_ot_var_get_axis_infos'

好像ld找不到动态库hb.h

这是我的文件:

src/main.rs

use std::ffi::CString;
use std::os::raw::c_char;

#[link(name = "myharfbuzz")]
extern "C" {
    fn example(s: *const std::os::raw::c_char, a: i32, b: i32);
}

fn main() {
    let prompt = CString::new("Rust").unwrap();

    unsafe {
        example(prompt.as_ptr(), 7, 11);
    }
}

src/c_ffi/myharfbuzz.c

#include <stdint.h>
#include <stdio.h>
#include <hb.h>
#include <hb-ot.h>
#include <stdint.h>



void example(int32_t a, int32_t b){
printf("%d + %d = %d\n", a, b, a + b);

char *filename = "/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc";
printf("%s", filename);

hb_blob_t *blob = hb_blob_create_from_file(filename);
hb_face_t *face = hb_face_create(blob, 0);
hb_ot_var_axis_info_t *axes_array;
int axes = hb_ot_var_get_axis_count(face);
hb_ot_var_get_axis_infos(face, 0, &axes, axes_array);
printf("%d", axes_array);
}

在我build.rs的包含路径设置,但ld发出链接错误:

use std::env;
use std::path::Path;
extern crate pkg_config;

fn main() {
    let out_dir = env::var("OUT_DIR").unwrap();
    println!("OUT_DIR = {:?}", out_dir);
    let harfbuzz_config = pkg_config::Config::new().probe("harfbuzz").unwrap();
    println!("{:?}", harfbuzz_config);

    let linked_path = harfbuzz_config.link_paths[0].clone();

    let mut builder = cc::Build::new();
    builder
        .files(&["src/c_ffi/myharfbuzz.c"])
        .includes(harfbuzz_config.include_paths)
        .includes(harfbuzz_config.link_paths)
        .flag(&format!("-lharfbuzz"))
        .compile(&format!("myharfbuzz"));

    println!("cargo:rerun-if-changed=build.rs");

    println!("cargo:rustc-link-search=native={:?}", linked_path);
    println!("cargo:rustc-link-search=native={}", out_dir);
    println!("cargo:rustc-link-lib=static=myharfbuzz");
}
4

1 回答 1

1

#[link]指令链接不太可能起作用,因为 Rust 不会花任何精力来搜索给定库的安装位置。

为了与 C/系统依赖项链接,您应该使用 sys crates。有harfbuzz-sys

于 2021-08-10T20:55:22.637 回答