无法使用 Rust FFI

问题描述

我想使用 Rust 文件 main.rs 来绑定链接动态库(例如 src/c_ffi/myharfbuzz.chb.h)的 C 文件 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,&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");
}

解决方法

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

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

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...