【问题标题】:How to use a C typedef struct and functions with that struct from Rust?如何将 C typedef 结构和函数与 Rust 中的结构一起使用?
【发布时间】:2018-05-31 07:12:26
【问题描述】:

我有这些 C 文件,我想使用来自 Rust 的 pair_addaddPAIR

adder.c

#include <stdlib.h>
#include "adder.h"

int pair_add(PAIR * ppair) {
    return ppair->x + ppair->y;
}

int add(int x, int y) {
    return x + y;
}

adder.h

typedef struct {
    int x;
    int y;
} PAIR;

int pair_add(PAIR * ppair);
int add(int, int);

我使用以下方法编译它们:

gcc -c adder.c
ar rc libadder.a adder.o  # Static link

documentation 没有详细说明如何集成 C typedef 结构,the example 用于返回和接受 i32 的函数。 Other online resources were also limited.

我尝试了以下但无法添加PAIR typedef:

extern crate libc;

use libc::c_int;

#[link(name = "adder")]
extern "C" {
    // Define PAIR

    // int pair_add(PAIR * ppair);
    fn pair_add(input: Pair) -> c_int;

    // int add(int, int);
    fn add(input1: c_int) -> c_int;
}

fn main() {}

【问题讨论】:

标签: rust extern ffi


【解决方案1】:

第一:

typedef struct {
    int x;
    int y;
} PAIR;

这声明了一个匿名结构,目前 Rust 不支持。有一个RFC 提议添加匿名类型。

其次,typedef 只是一个别名,结构的名称对于兼容并不重要。这意味着您可以简单地执行以下操作:

extern crate libc;
use libc::c_int;

#[repr(C)]
struct PAIR {
    x: c_int,
    y: c_int,
}

// optional "equivalent" of typedef
type Pair = PAIR;

extern "C" {
    fn pair_add(input: *mut Pair) -> c_int;
    // could be
    // fn pair_add(input: *mut PAIR) -> c_int;
}

你可以很容易地忽略 typedef 并使用 PAIR 作为这个结构的名称。您甚至可以只写struct PAIR; 使其不透明。

【讨论】:

  • 您不需要匹配结构的名称以开始,您可以使用#[repr(C)] struct Pair { x: c_int, y: c_int }。你可以给它任何你想要的名字,因为正如你所提到的,这个名字对编译器来说并不重要。
  • 让它不透明——我用它来定义一个不透明的类型。 Another Q&A has suggestions,但 struct PAIR; 将允许 anyone 创建 PAIR 的实例,如果它不透明,则不应允许。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多